69#include "llvm/IR/IntrinsicsPowerPC.h"
104#define DEBUG_TYPE "ppc-lowering"
125 "ppc-quadword-atomics",
131 cl::desc(
"disable vector permute decomposition"),
135 "disable-auto-paired-vec-st",
136 cl::desc(
"disable automatically generated 32byte paired vector stores"),
141STATISTIC(ShufflesHandledWithVPERM,
"Number of shuffles lowered to a VPERM");
142STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
159 initializeAddrModeMap();
162 bool isPPC64 = Subtarget.
isPPC64();
226 if (!Subtarget.
hasSPE()) {
235 for (
MVT VT : ScalarIntVTs) {
245 if (isPPC64 || Subtarget.
hasFPCVT()) {
354 if (!Subtarget.
hasSPE()) {
543 if (
TM.Options.UnsafeFPMath) {
769 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
998 if (
TM.Options.UnsafeFPMath) {
1235 }
else if (Subtarget.
hasVSX()) {
1308 if (Subtarget.
hasMMA()) {
1506void PPCTargetLowering::initializeAddrModeMap() {
1557 if (MaxAlign == MaxMaxAlign)
1560 if (MaxMaxAlign >= 32 &&
1561 VTy->getPrimitiveSizeInBits().getFixedSize() >= 256)
1562 MaxAlign =
Align(32);
1563 else if (VTy->getPrimitiveSizeInBits().getFixedSize() >= 128 &&
1565 MaxAlign =
Align(16);
1569 if (EltAlign > MaxAlign)
1570 MaxAlign = EltAlign;
1572 for (
auto *EltTy : STy->elements()) {
1575 if (EltAlign > MaxAlign)
1576 MaxAlign = EltAlign;
1577 if (MaxAlign == MaxMaxAlign)
1592 return Alignment.value();
1600 return Subtarget.
hasSPE();
1622 return "PPCISD::FP_TO_UINT_IN_VSR,";
1624 return "PPCISD::FP_TO_SINT_IN_VSR";
1628 return "PPCISD::FTSQRT";
1630 return "PPCISD::FSQRT";
1635 return "PPCISD::XXSPLTI_SP_TO_DP";
1637 return "PPCISD::XXSPLTI32DX";
1659 return "PPCISD::CALL_RM";
1661 return "PPCISD::CALL_NOP_RM";
1663 return "PPCISD::CALL_NOTOC_RM";
1668 return "PPCISD::BCTRL_RM";
1670 return "PPCISD::BCTRL_LOAD_TOC_RM";
1682 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1684 return "PPCISD::ANDI_rec_1_EQ_BIT";
1686 return "PPCISD::ANDI_rec_1_GT_BIT";
1701 return "PPCISD::ST_VSR_SCAL_INT";
1727 return "PPCISD::PADDI_DTPREL";
1744 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1746 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1756 return "PPCISD::STRICT_FADDRTZ";
1758 return "PPCISD::STRICT_FCTIDZ";
1760 return "PPCISD::STRICT_FCTIWZ";
1762 return "PPCISD::STRICT_FCTIDUZ";
1764 return "PPCISD::STRICT_FCTIWUZ";
1766 return "PPCISD::STRICT_FCFID";
1768 return "PPCISD::STRICT_FCFIDU";
1770 return "PPCISD::STRICT_FCFIDS";
1772 return "PPCISD::STRICT_FCFIDUS";
1798 return CFP->getValueAPF().isZero();
1803 return CFP->getValueAPF().isZero();
1811 return Op < 0 || Op == Val;
1823 if (ShuffleKind == 0) {
1826 for (
unsigned i = 0; i != 16; ++i)
1829 }
else if (ShuffleKind == 2) {
1832 for (
unsigned i = 0; i != 16; ++i)
1835 }
else if (ShuffleKind == 1) {
1836 unsigned j = IsLE ? 0 : 1;
1837 for (
unsigned i = 0; i != 8; ++i)
1854 if (ShuffleKind == 0) {
1857 for (
unsigned i = 0; i != 16; i += 2)
1861 }
else if (ShuffleKind == 2) {
1864 for (
unsigned i = 0; i != 16; i += 2)
1868 }
else if (ShuffleKind == 1) {
1869 unsigned j = IsLE ? 0 : 2;
1870 for (
unsigned i = 0; i != 8; i += 2)
1895 if (ShuffleKind == 0) {
1898 for (
unsigned i = 0; i != 16; i += 4)
1904 }
else if (ShuffleKind == 2) {
1907 for (
unsigned i = 0; i != 16; i += 4)
1913 }
else if (ShuffleKind == 1) {
1914 unsigned j = IsLE ? 0 : 4;
1915 for (
unsigned i = 0; i != 8; i += 4)
1932 unsigned LHSStart,
unsigned RHSStart) {
1935 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1936 "Unsupported merge size!");
1938 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1939 for (
unsigned j = 0; j != UnitSize; ++j) {
1941 LHSStart+j+i*UnitSize) ||
1943 RHSStart+j+i*UnitSize))
1958 if (ShuffleKind == 1)
1960 else if (ShuffleKind == 2)
1965 if (ShuffleKind == 1)
1967 else if (ShuffleKind == 0)
1983 if (ShuffleKind == 1)
1985 else if (ShuffleKind == 2)
1990 if (ShuffleKind == 1)
1992 else if (ShuffleKind == 0)
2042 unsigned RHSStartValue) {
2046 for (
unsigned i = 0; i < 2; ++i)
2047 for (
unsigned j = 0; j < 4; ++j)
2049 i*RHSStartValue+j+IndexOffset) ||
2051 i*RHSStartValue+j+IndexOffset+8))
2073 unsigned indexOffset = CheckEven ? 4 : 0;
2074 if (ShuffleKind == 1)
2076 else if (ShuffleKind == 2)
2082 unsigned indexOffset = CheckEven ? 0 : 4;
2083 if (ShuffleKind == 1)
2085 else if (ShuffleKind == 0)
2108 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2111 if (i == 16)
return -1;
2116 if (ShiftAmt < i)
return -1;
2121 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2123 for (++i; i != 16; ++i)
2126 }
else if (ShuffleKind == 1) {
2128 for (++i; i != 16; ++i)
2135 ShiftAmt = 16 - ShiftAmt;
2144 EVT VT =
N->getValueType(0);
2146 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2149 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2153 if (
N->getMaskElt(0) % EltSize != 0)
2158 unsigned ElementBase =
N->getMaskElt(0);
2161 if (ElementBase >= 16)
2166 for (
unsigned i = 1; i != EltSize; ++i)
2167 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2170 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2171 if (
N->getMaskElt(i) < 0)
continue;
2172 for (
unsigned j = 0; j != EltSize; ++j)
2173 if (
N->getMaskElt(i+j) !=
N->getMaskElt(j))
2190 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2191 "Unexpected element width.");
2192 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2194 unsigned NumOfElem = 16 / Width;
2195 unsigned MaskVal[16];
2196 for (
unsigned i = 0; i < NumOfElem; ++i) {
2197 MaskVal[0] =
N->getMaskElt(i * Width);
2198 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2200 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2204 for (
unsigned int j = 1; j < Width; ++j) {
2205 MaskVal[j] =
N->getMaskElt(i * Width + j);
2206 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2216 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2221 unsigned M0 =
N->getMaskElt(0) / 4;
2222 unsigned M1 =
N->getMaskElt(4) / 4;
2223 unsigned M2 =
N->getMaskElt(8) / 4;
2224 unsigned M3 =
N->getMaskElt(12) / 4;
2225 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2226 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2231 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2232 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2233 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2234 InsertAtByte = IsLE ? 12 : 0;
2239 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2240 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2241 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2242 InsertAtByte = IsLE ? 8 : 4;
2247 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2248 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2249 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2250 InsertAtByte = IsLE ? 4 : 8;
2255 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2256 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2257 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2258 InsertAtByte = IsLE ? 0 : 12;
2265 if (
N->getOperand(1).isUndef()) {
2268 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2269 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2270 InsertAtByte = IsLE ? 12 : 0;
2273 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2274 InsertAtByte = IsLE ? 8 : 4;
2277 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2278 InsertAtByte = IsLE ? 4 : 8;
2281 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2282 InsertAtByte = IsLE ? 0 : 12;
2291 bool &Swap,
bool IsLE) {
2298 unsigned M0 =
N->getMaskElt(0) / 4;
2299 unsigned M1 =
N->getMaskElt(4) / 4;
2300 unsigned M2 =
N->getMaskElt(8) / 4;
2301 unsigned M3 =
N->getMaskElt(12) / 4;
2305 if (
N->getOperand(1).isUndef()) {
2306 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2307 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2310 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2316 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2320 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2325 ShiftElts = (8 -
M0) % 8;
2326 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2331 ShiftElts = (4 -
M0) % 4;
2336 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2341 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2358 for (
int i = 0; i < 16; i += Width)
2359 if (
N->getMaskElt(i) != i + Width - 1)
2390 bool &Swap,
bool IsLE) {
2397 unsigned M0 =
N->getMaskElt(0) / 8;
2398 unsigned M1 =
N->getMaskElt(8) / 8;
2399 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2403 if (
N->getOperand(1).isUndef()) {
2404 if ((
M0 |
M1) < 2) {
2405 DM = IsLE ? (((~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2413 if (
M0 > 1 &&
M1 < 2) {
2423 DM = (((~M1) & 1) << 1) + ((~
M0) & 1);
2428 }
else if (
M0 > 1 &&
M1 < 2) {
2436 DM = (
M0 << 1) + (
M1 & 1);
2456 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2473 if (EltSize < ByteSize) {
2474 unsigned Multiple = ByteSize/EltSize;
2476 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2479 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2480 if (
N->getOperand(i).isUndef())
continue;
2484 if (!UniquedVals[i&(Multiple-1)].getNode())
2486 else if (UniquedVals[i&(Multiple-1)] !=
N->
getOperand(i))
2496 bool LeadingZero =
true;
2497 bool LeadingOnes =
true;
2498 for (
unsigned i = 0; i != Multiple-1; ++i) {
2499 if (!UniquedVals[i].getNode())
continue;
2506 if (!UniquedVals[Multiple-1].getNode())
2513 if (!UniquedVals[Multiple-1].getNode())
2524 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2525 if (
N->getOperand(i).isUndef())
continue;
2534 unsigned ValSizeInBytes = EltSize;
2537 Value = CN->getZExtValue();
2539 assert(CN->getValueType(0) ==
MVT::f32 &&
"Only one legal FP vector type!");
2546 if (ValSizeInBytes < ByteSize)
return SDValue();
2557 if (MaskVal == 0)
return SDValue();
2599 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2609 if (Memop->getMemoryVT() ==
MVT::f64) {
2610 Base =
N.getOperand(0);
2654 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2659 Base =
N.getOperand(0);
2662 }
else if (
N.getOpcode() ==
ISD::OR) {
2664 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2676 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2677 Base =
N.getOperand(0);
2748 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2754 Base =
N.getOperand(0);
2757 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2760 &&
"Cannot handle constant offsets yet!");
2766 Base =
N.getOperand(0);
2769 }
else if (
N.getOpcode() ==
ISD::OR) {
2772 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2786 Base =
N.getOperand(0);
2799 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2802 CN->getValueType(0));
2807 if ((CN->getValueType(0) ==
MVT::i32 ||
2808 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2809 (!EncodingAlignment ||
2810 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2811 int Addr = (int)CN->getZExtValue();
2901 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2902 Base =
N.getOperand(0);
2946 EVT MemVT = LD->getMemoryVT();
2953 if (!ST.hasP8Vector())
2958 if (!ST.hasP9Vector())
2971 if (UI.getUse().get().getResNo() == 0 &&
2993 Ptr = LD->getBasePtr();
2994 VT = LD->getMemoryVT();
2995 Alignment = LD->getAlign();
2997 Ptr = ST->getBasePtr();
2998 VT = ST->getMemoryVT();
2999 Alignment = ST->getAlign();
3043 if (Alignment <
Align(4))
3070 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3112 const bool Is64Bit = Subtarget.
isPPC64();
3127 EVT PtrVT =
Op.getValueType();
3143 return getTOCEntry(DAG,
SDLoc(CP), GA);
3146 unsigned MOHiFlag, MOLoFlag;
3153 return getTOCEntry(DAG,
SDLoc(CP), GA);
3213 EVT PtrVT = Op.getValueType();
3231 return getTOCEntry(DAG,
SDLoc(JT), GA);
3234 unsigned MOHiFlag, MOLoFlag;
3241 return getTOCEntry(DAG,
SDLoc(GA), GA);
3251 EVT PtrVT =
Op.getValueType();
3270 return getTOCEntry(DAG,
SDLoc(BASDN), GA);
3279 unsigned MOHiFlag, MOLoFlag;
3290 return LowerGlobalTLSAddressAIX(Op, DAG);
3292 return LowerGlobalTLSAddressLinux(Op, DAG);
3316 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3317 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3335 bool is64bit = Subtarget.
isPPC64();
3383 if (!
TM.isPositionIndependent())
3442 PtrVT, GOTPtr, TGA, TGA);
3444 PtrVT, TLSAddr, TGA);
3453 EVT PtrVT =
Op.getValueType();
3479 return getTOCEntry(DAG,
DL, GA);
3482 unsigned MOHiFlag, MOLoFlag;
3490 return getTOCEntry(DAG,
DL, GA);
3502 bool IsStrict =
Op->isStrictFPOpcode();
3505 SDValue LHS =
Op.getOperand(IsStrict ? 1 : 0);
3506 SDValue RHS =
Op.getOperand(IsStrict ? 2 : 1);
3508 EVT LHSVT = LHS.getValueType();
3514 "SETCC for f128 is already legal under Power9!");
3525 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3538 int ShuffV[] = {1, 0, 3, 2};
3560 if (
C->isAllOnes() ||
C->isZero())
3570 EVT VT =
Op.getValueType();
3579 EVT VT =
Node->getValueType(0);
3624 InChain = OverflowArea.
getValue(1);
3670 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3677 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3681 return DAG.
getMemcpy(
Op.getOperand(0), Op,
Op.getOperand(1),
Op.getOperand(2),
3692 return Op.getOperand(0);
3699 assert((
Op.getOpcode() == ISD::INLINEASM ||
3700 Op.getOpcode() == ISD::INLINEASM_BR) &&
3701 "Expecting Inline ASM node.");
3710 unsigned NumOps =
Op.getNumOperands();
3711 if (
Op.getOperand(NumOps - 1).getValueType() ==
MVT::Glue)
3731 for (; NumVals; --NumVals, ++i) {
3733 if (Reg != PPC::LR && Reg != PPC::LR8)
3758 bool isPPC64 = (PtrVT ==
MVT::i64);
3764 Entry.
Ty = IntPtrTy;
3765 Entry.Node = Trmp;
Args.push_back(Entry);
3768 Entry.Node = DAG.
getConstant(isPPC64 ? 48 : 40, dl,
3770 Args.push_back(Entry);
3772 Entry.Node = FPtr;
Args.push_back(Entry);
3773 Entry.Node = Nest;
Args.push_back(Entry);
3777 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3781 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3782 return CallResult.second;
3797 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3832 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
3856 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
3859 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
3861 nextOffset += FrameOffset;
3862 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
3865 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
3871static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
3872 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
3873 PPC::F11, PPC::F12, PPC::F13};
3878 unsigned PtrByteSize) {
3880 if (Flags.isByVal())
3881 ArgSize = Flags.getByValSize();
3885 if (!Flags.isInConsecutiveRegs())
3886 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
3895 unsigned PtrByteSize) {
3896 Align Alignment(PtrByteSize);
3903 Alignment =
Align(16);
3906 if (Flags.isByVal()) {
3907 auto BVAlign = Flags.getNonZeroByValAlign();
3908 if (BVAlign > PtrByteSize) {
3909 if (BVAlign.value() % PtrByteSize != 0)
3911 "ByVal alignment is not a multiple of the pointer size");
3913 Alignment = BVAlign;
3918 if (Flags.isInConsecutiveRegs()) {
3936 unsigned PtrByteSize,
unsigned LinkageSize,
3937 unsigned ParamAreaSize,
unsigned &ArgOffset,
3938 unsigned &AvailableFPRs,
3939 unsigned &AvailableVRs) {
3940 bool UseMemory =
false;
3945 ArgOffset =
alignTo(ArgOffset, Alignment);
3948 if (ArgOffset >= LinkageSize + ParamAreaSize)
3953 if (Flags.isInConsecutiveRegsLast())
3954 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
3957 if (ArgOffset > LinkageSize + ParamAreaSize)
3962 if (!Flags.isByVal()) {
3964 if (AvailableFPRs > 0) {
3972 if (AvailableVRs > 0) {
3984 unsigned NumBytes) {
3988SDValue PPCTargetLowering::LowerFormalArguments(
3989 SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
3993 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
3996 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
3999 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4003SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4004 SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
4045 const Align PtrAlign(4);
4054 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4056 CCInfo.PreAnalyzeFormalArguments(Ins);
4059 CCInfo.clearWasPPCF128();
4061 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4074 RC = &PPC::GPRCRegClass;
4078 RC = &PPC::VSSRCRegClass;
4079 else if (Subtarget.
hasSPE())
4080 RC = &PPC::GPRCRegClass;
4082 RC = &PPC::F4RCRegClass;
4086 RC = &PPC::VSFRCRegClass;
4087 else if (Subtarget.
hasSPE())
4089 RC = &PPC::GPRCRegClass;
4091 RC = &PPC::F8RCRegClass;
4096 RC = &PPC::VRRCRegClass;
4099 RC = &PPC::VRRCRegClass;
4103 RC = &PPC::VRRCRegClass;
4111 assert(i + 1 < e &&
"No second half of double precision argument");
4139 ArgOffset += ArgSize - ObjSize;
4157 CCByValInfo.AllocateStack(CCInfo.getNextStackOffset(), PtrAlign);
4162 unsigned MinReservedArea = CCByValInfo.getNextStackOffset();
4163 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4179 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4180 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4185 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4197 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4202 CCInfo.getNextStackOffset(),
true));
4211 for (
unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
4215 VReg = MF.
addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
4230 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4234 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4247 if (!MemOps.
empty())
4258 const SDLoc &dl)
const {
4262 else if (Flags.isZExt())
4269SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4270 SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
4282 "fastcc not supported on varargs functions");
4288 unsigned PtrByteSize = 8;
4292 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4293 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4296 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4297 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4310 bool HasParameterArea = !isELFv2ABI || isVarArg;
4311 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4312 unsigned NumBytes = LinkageSize;
4313 unsigned AvailableFPRs = Num_FPR_Regs;
4314 unsigned AvailableVRs = Num_VR_Regs;
4315 for (
unsigned i = 0, e =
Ins.size(); i != e; ++i) {
4316 if (Ins[i].Flags.isNest())
4320 PtrByteSize, LinkageSize, ParamAreaSize,
4321 NumBytes, AvailableFPRs, AvailableVRs))
4322 HasParameterArea =
true;
4329 unsigned ArgOffset = LinkageSize;
4330 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4333 unsigned CurArgIdx = 0;
4334 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4336 bool needsLoad =
false;
4337 EVT ObjectVT =
Ins[ArgNo].VT;
4338 EVT OrigVT =
Ins[ArgNo].ArgVT;
4340 unsigned ArgSize = ObjSize;
4342 if (Ins[ArgNo].isOrigArg()) {
4343 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4344 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4349 unsigned CurArgOffset;
4351 auto ComputeArgOffset = [&]() {
4355 ArgOffset =
alignTo(ArgOffset, Alignment);
4356 CurArgOffset = ArgOffset;
4363 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4364 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4369 if (Flags.isByVal()) {
4370 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4376 ObjSize = Flags.getByValSize();
4377 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4399 if (HasParameterArea ||
4400 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4407 if (ObjSize < PtrByteSize) {
4411 if (!isLittleEndian) {
4417 if (GPR_idx != Num_GPR_Regs) {
4429 ArgOffset += PtrByteSize;
4438 for (
unsigned j = 0; j < ArgSize; j += PtrByteSize) {
4439 if (GPR_idx == Num_GPR_Regs)
4450 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4458 ArgOffset += ArgSize;
4467 if (Flags.isNest()) {
4473 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4481 if (GPR_idx != Num_GPR_Regs) {
4489 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4495 ArgSize = PtrByteSize;
4506 if (FPR_idx != Num_FPR_Regs) {
4512 ? &PPC::VSSRCRegClass
4513 : &PPC::F4RCRegClass);
4516 ? &PPC::VSFRCRegClass
4517 : &PPC::F8RCRegClass);
4533 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4539 ArgVal = DAG.
getNode(ISD::BITCAST, dl, ObjectVT, ArgVal);
4551 ArgSize = Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4552 ArgOffset += ArgSize;
4553 if (Flags.isInConsecutiveRegsLast())
4554 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4568 if (VR_idx != Num_VR_Regs) {
4585 if (ObjSize < ArgSize && !isLittleEndian)
4586 CurArgOffset += ArgSize - ObjSize;
4596 unsigned MinReservedArea;
4597 if (HasParameterArea)
4598 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4600 MinReservedArea = LinkageSize;
4617 int Depth = ArgOffset;
4626 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4627 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4639 if (!MemOps.
empty())
4648 unsigned ParamSize) {
4650 if (!isTailCall)
return 0;
4654 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4656 if (SPDiff < FI->getTailCallSPDelta())
4671 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4687 if (!
TM.shouldAssumeDSOLocal(*Caller->getParent(), GV))
4732 if (
TM.getFunctionSections() || GV->
hasComdat() || Caller->hasComdat() ||
4736 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4748 const unsigned PtrByteSize = 8;
4752 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4753 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4756 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4757 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4761 const unsigned NumFPRs = 13;
4763 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4765 unsigned NumBytes = LinkageSize;
4766 unsigned AvailableFPRs = NumFPRs;
4767 unsigned AvailableVRs = NumVRs;
4770 if (Param.Flags.isNest())
continue;
4773 LinkageSize, ParamAreaSize, NumBytes,
4774 AvailableFPRs, AvailableVRs))
4785 auto CalleeArgEnd = CB.
arg_end();
4788 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4789 const Value* CalleeArg = *CalleeArgIter;
4790 const Value* CallerArg = &(*CallerArgIter);
4791 if (CalleeArg == CallerArg)
4812 CallingConv::ID CalleeCC) {
4814 auto isTailCallableCC = [] (CallingConv::ID CC){
4817 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
4827bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
4833 if (
DisableSCO && !TailCallOpt)
return false;
4836 if (isVarArg)
return false;
4868 if (
Caller.getCallingConv() != CalleeCC &&
4915PPCTargetLowering::IsEligibleForTailCallOptimization(
SDValue Callee,
4916 CallingConv::ID CalleeCC,
4931 for (
unsigned i = 0; i !=
Ins.size(); i++) {
4933 if (Flags.isByVal())
return false;
4943 return G->getGlobal()->hasHiddenVisibility()
4944 ||
G->getGlobal()->hasProtectedVisibility();
4954 if (!
C)
return nullptr;
4956 int Addr =
C->getZExtValue();
4957 if ((
Addr & 3) != 0 ||
4963 (
int)
C->getZExtValue() >> 2,
SDLoc(Op),
4970struct TailCallArgumentInfo {
4975 TailCallArgumentInfo() =
default;
4985 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
4987 SDValue FIN = TailCallArgs[i].FrameIdxOp;
4988 int FI = TailCallArgs[i].FrameIdx;
4991 Chain, dl,
Arg, FIN,
5000 int SPDiff,
const SDLoc &dl) {
5006 bool isPPC64 = Subtarget.
isPPC64();
5007 int SlotSize = isPPC64 ? 8 : 4;
5008 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5010 NewRetAddrLoc,
true);
5013 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5025 int Offset = ArgOffset + SPDiff;
5026 uint32_t OpSize = (
Arg.getValueSizeInBits() + 7) / 8;
5030 TailCallArgumentInfo
Info;
5032 Info.FrameIdxOp = FIN;
5040SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5046 LROpOut = getReturnAddrFrameIndex(DAG);
5063 return DAG.
getMemcpy(Chain, dl, Dst, Src, SizeNode,
5064 Flags.getNonZeroByValAlign(),
false,
false,
false,
5072 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5095 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5105 if (!MemOpChains2.
empty())
5125 return G->getGlobal()->getValueType()->isFunctionTy();
5131SDValue PPCTargetLowering::LowerCallResult(
5132 SDValue Chain,
SDValue InFlag, CallingConv::ID CallConv,
bool isVarArg,
5139 CCRetInfo.AnalyzeCallResult(
5145 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5226 bool IsStrictFPCall =
false) {
5230 unsigned RetOpc = 0;
5259 if (IsStrictFPCall) {
5290 auto isLocalCallee = [&]() {
5307 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5322 return getAIXFuncEntryPointSymbolSDNode(GV);
5329 const char *SymName = S->getSymbol();
5336 return getAIXFuncEntryPointSymbolSDNode(
F);
5342 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5350 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5363 "Expected a CALLSEQ_STARTSDNode.");
5438 const unsigned Alignment = Subtarget.
isPPC64() ? 8 : 4;
5442 Alignment, MMOFlags);
5449 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5456 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5468 "Nest parameter is not supported on AIX.");
5484 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5487 const bool IsPPC64 = Subtarget.
isPPC64();
5536 for (
unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5538 RegsToPass[i].second.getValueType()));
5555 assert(Mask &&
"Missing call preserved mask for calling convention");
5563SDValue PPCTargetLowering::FinishCall(
5578 if (!CFlags.IsIndirect)
5582 dl, CFlags.HasNest, Subtarget);
5592 if (CFlags.IsTailCall) {
5601 "Expecting a global address, external symbol, absolute value, "
5602 "register or an indirect tail call when PC Relative calls are "
5606 "Unexpected call opcode for a tail call.");
5612 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes, Ops);
5629 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5644 CallingConv::ID CallConv = CLI.
CallConv;
5653 isTailCall = IsEligibleForTailCallOptimization_64SVR4(
5654 Callee, CallConv, CB, isVarArg, Outs, Ins, DAG);
5656 isTailCall = IsEligibleForTailCallOptimization(
Callee, CallConv, isVarArg,
5671 "Callee should be an llvm::Function object.");
5674 <<
"\nTCO callee: ");
5681 "site marked musttail");
5691 CallConv, isTailCall, isVarArg, isPatchPoint,
5699 return LowerCall_AIX(Chain,
Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5704 return LowerCall_64SVR4(Chain,
Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5706 return LowerCall_32SVR4(Chain,
Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5710SDValue PPCTargetLowering::LowerCall_32SVR4(
5720 const CallingConv::ID CallConv = CFlags.CallConv;
5721 const bool IsVarArg = CFlags.IsVarArg;
5722 const bool IsTailCall = CFlags.IsTailCall;
5728 const Align PtrAlign(4);
5753 CCInfo.PreAnalyzeCallOperands(Outs);
5759 unsigned NumArgs = Outs.
size();
5761 for (
unsigned i = 0; i != NumArgs; ++i) {
5762 MVT ArgVT = Outs[i].VT;
5766 if (Outs[i].IsFixed) {
5776 errs() <<
"Call operand #" << i <<
" has unhandled type "
5786 CCInfo.clearWasPPCF128();
5793 CCByValInfo.AllocateStack(CCInfo.getNextStackOffset(), PtrAlign);
5800 unsigned NumBytes = CCByValInfo.getNextStackOffset();
5814 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
5825 bool seenFloatArg =
false;
5830 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
5832 ++i, ++RealArgIdx) {
5837 if (Flags.isByVal()) {
5842 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
5865 Chain = CallSeqStart = NewCallSeqStart;
5891 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
5915 if (!MemOpChains.
empty())
5921 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
5922 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
5923 RegsToPass[i].second, InFlag);
5931 SDValue Ops[] = { Chain, InFlag };
5943 return FinishCall(CFlags, dl, DAG, RegsToPass, InFlag, Chain, CallSeqStart,
5944 Callee, SPDiff, NumBytes, Ins, InVals, CB);
5949SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
5961 return NewCallSeqStart;
5964SDValue PPCTargetLowering::LowerCall_64SVR4(
5973 unsigned NumOps = Outs.
size();
5974 bool IsSibCall =
false;
5978 unsigned PtrByteSize = 8;
5993 assert(!(IsFastCall && CFlags.IsVarArg) &&
5994 "fastcc not supported on varargs functions");
6001 unsigned NumBytes = LinkageSize;
6002 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6005 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6006 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6009 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6010 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6021 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6022 if (!HasParameterArea) {
6023 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6024 unsigned AvailableFPRs = NumFPRs;
6025 unsigned AvailableVRs = NumVRs;
6026 unsigned NumBytesTmp = NumBytes;
6027 for (
unsigned i = 0; i != NumOps; ++i) {
6028 if (Outs[i].Flags.isNest())
continue;
6030 PtrByteSize, LinkageSize, ParamAreaSize,
6031 NumBytesTmp, AvailableFPRs, AvailableVRs))
6032 HasParameterArea =
true;
6038 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6043 HasParameterArea =
false;
6046 for (
unsigned i = 0; i != NumOps; ++i) {
6048 EVT ArgVT = Outs[i].VT;
6049 EVT OrigVT = Outs[i].ArgVT;
6055 if (Flags.isByVal()) {
6056 NumGPRsUsed += (Flags.getByValSize()+7)/8;
6057 if (NumGPRsUsed > NumGPRs)
6058 HasParameterArea =
true;
6065 if (++NumGPRsUsed <= NumGPRs)
6075 if (++NumVRsUsed <= NumVRs)
6079 if (++NumVRsUsed <= NumVRs)
6084 if (++NumFPRsUsed <= NumFPRs)
6088 HasParameterArea =
true;
6095 NumBytes =
alignTo(NumBytes, Alignement);
6098 if (Flags.isInConsecutiveRegsLast())
6099 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6102 unsigned NumBytesActuallyUsed = NumBytes;
6112 if (HasParameterArea)
6113 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6115 NumBytes = LinkageSize;
6130 if (CFlags.IsTailCall)
6142 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6153 unsigned ArgOffset = LinkageSize;
6159 for (
unsigned i = 0; i != NumOps; ++i) {
6162 EVT ArgVT = Outs[i].VT;
6163 EVT OrigVT = Outs[i].ArgVT;
6172 auto ComputePtrOff = [&]() {
6176 ArgOffset =
alignTo(ArgOffset, Alignment);
6187 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6188 GPR_idx = std::min(GPR_idx, NumGPRs);
6201 if (Flags.isByVal()) {
6207 unsigned Size = Flags.getByValSize();
6220 if (GPR_idx != NumGPRs) {
6224 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6226 ArgOffset += PtrByteSize;
6231 if (GPR_idx == NumGPRs &&
Size < 8) {
6233 if (!isLittleEndian) {
6238 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, AddPtr,
6241 ArgOffset += PtrByteSize;
6250 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6251 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, PtrOff,
6256 if (
Size < 8 && GPR_idx != NumGPRs) {
6266 if (!isLittleEndian) {
6270 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, AddPtr,
6278 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6281 ArgOffset += PtrByteSize;
6287 for (
unsigned j=0; j<
Size; j+=PtrByteSize) {
6290 if (GPR_idx != NumGPRs) {
6291 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6297 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6298 ArgOffset += PtrByteSize;
6300 ArgOffset += ((
Size - j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6307 switch (
Arg.getSimpleValueType().SimpleTy) {
6312 if (Flags.isNest()) {
6321 if (GPR_idx != NumGPRs) {
6322 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++],
Arg));
6327 assert(HasParameterArea &&
6328 "Parameter area must exist to pass an argument in memory.");
6330 true, CFlags.IsTailCall,
false, MemOpChains,
6331 TailCallArguments, dl);
6333 ArgOffset += PtrByteSize;
6336 ArgOffset += PtrByteSize;
6349 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6350 bool NeededLoad =
false;
6353 if (FPR_idx != NumFPRs)
6357 if (!NeedGPROrStack)
6359 else if (GPR_idx != NumGPRs && !IsFastCall) {
6373 }
else if (!Flags.isInConsecutiveRegs()) {
6379 }
else if (ArgOffset % PtrByteSize != 0) {
6383 if (!isLittleEndian)
6388 }
else if (Flags.isInConsecutiveRegsLast()) {
6391 if (!isLittleEndian)
6401 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6409 !isLittleEndian && !Flags.isInConsecutiveRegs()) {
6414 assert(HasParameterArea &&
6415 "Parameter area must exist to pass an argument in memory.");
6417 true, CFlags.IsTailCall,
false, MemOpChains,
6418 TailCallArguments, dl);
6425 if (!IsFastCall || NeededLoad) {
6427 Flags.isInConsecutiveRegs()) ? 4 : 8;
6428 if (Flags.isInConsecutiveRegsLast())
6429 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6449 if (CFlags.IsVarArg) {
6450 assert(HasParameterArea &&
6451 "Parameter area must exist if we have a varargs call.");
6457 if (VR_idx != NumVRs) {
6461 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6464 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6465 if (GPR_idx == NumGPRs)
6472 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6478 if (VR_idx != NumVRs) {
6479 RegsToPass.
push_back(std::make_pair(VR[VR_idx++],
Arg));
6484 assert(HasParameterArea &&
6485 "Parameter area must exist to pass an argument in memory.");
6487 true, CFlags.IsTailCall,
true, MemOpChains,
6488 TailCallArguments, dl);
6499 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6500 "mismatch in size of parameter area");
6501 (
void)NumBytesActuallyUsed;
6503 if (!MemOpChains.
empty())
6509 if (CFlags.IsIndirect) {
6513 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6528 if (isELFv2ABI && !CFlags.IsPatchPoint)
6535 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6536 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6537 RegsToPass[i].second, InFlag);
6541 if (CFlags.IsTailCall && !IsSibCall)
6545 return FinishCall(CFlags, dl, DAG, RegsToPass, InFlag, Chain, CallSeqStart,
6546 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6553 "Required alignment greater than stack alignment.");
6573 return RequiredAlign <= 8;
6578 return RequiredAlign <= 4;
6587 State.getMachineFunction().getSubtarget());
6588 const bool IsPPC64 = Subtarget.
isPPC64();
6599 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6600 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6602 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6603 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6606 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6607 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6608 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6613 "register width are not supported.");
6619 if (ByValSize == 0) {
6621 State.getNextStackOffset(), RegVT,
6626 const unsigned StackSize =
alignTo(ByValSize, PtrAlign);
6627 unsigned Offset = State.AllocateStack(StackSize, PtrAlign);
6630 if (
unsigned Reg = State.AllocateReg(IsPPC64 ? GPR_64 : GPR_32))
6648 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6652 const unsigned Offset = State.AllocateStack(PtrAlign.
value(), PtrAlign);
6657 if (
unsigned Reg = State.AllocateReg(IsPPC64 ? GPR_64 : GPR_32))
6671 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6672 unsigned FReg = State.AllocateReg(
FPR);
6677 for (
unsigned I = 0;
I < StoreSize;
I += PtrAlign.
value()) {
6678 if (
unsigned Reg = State.AllocateReg(IsPPC64 ? GPR_64 : GPR_32)) {
6679 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6680 if (State.isVarArg()) {
6712 const unsigned VecSize = 16;
6713 const Align VecAlign(VecSize);
6715 if (!State.isVarArg()) {
6718 if (
unsigned VReg = State.AllocateReg(VR)) {
6725 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6730 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6733 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
6736 while (NextRegIndex != GPRs.
size() &&
6739 unsigned Reg = State.AllocateReg(GPRs);
6740 State.AllocateStack(PtrSize, PtrAlign);
6741 assert(Reg &&
"Allocating register unexpectedly failed.");
6743 NextRegIndex = State.getFirstUnallocated(GPRs);
6750 if (State.isFixed(ValNo)) {
6751 if (
unsigned VReg = State.AllocateReg(VR)) {
6754 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
6755 State.AllocateReg(GPRs);
6756 State.AllocateStack(VecSize, VecAlign);
6760 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6766 if (NextRegIndex == GPRs.
size()) {
6767 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6775 if (GPRs[NextRegIndex] == PPC::R9) {
6776 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6780 const unsigned FirstReg = State.AllocateReg(PPC::R9);
6781 const unsigned SecondReg = State.AllocateReg(PPC::R10);
6782 assert(FirstReg && SecondReg &&
6783 "Allocating R9 or R10 unexpectedly failed.");
6794 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6797 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
6798 const unsigned Reg = State.AllocateReg(GPRs);
6799 assert(Reg &&
"Failed to allocated register for vararg vector argument");
6815 "i64 should have been split for 32-bit codegen.");
6823 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
6825 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
6827 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
6835 return &PPC::VRRCRegClass;
6848 else if (Flags.isZExt())
6858 if (PPC::GPRCRegClass.
contains(Reg)) {
6859 assert(Reg >= PPC::R3 && Reg <= PPC::R10 &&
6860 "Reg must be a valid argument register!");
6861 return LASize + 4 * (Reg - PPC::R3);
6864 if (PPC::G8RCRegClass.
contains(Reg)) {
6865 assert(Reg >= PPC::X3 && Reg <= PPC::X10 &&
6866 "Reg must be a valid argument register!");
6867 return LASize + 8 * (Reg - PPC::X3);
6913SDValue PPCTargetLowering::LowerFormalArguments_AIX(
6914 SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
6920 "Unexpected calling convention!");
6930 const bool IsPPC64 = Subtarget.
isPPC64();
6931 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
6943 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
6944 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
6948 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
6962 auto HandleMemLoc = [&]() {
6965 assert((ValSize <= LocSize) &&
6966 "Object size is larger than size of MemLoc");
6969 if (LocSize > ValSize)
6970 CurArgOffset += LocSize - ValSize;
6972 const bool IsImmutable =
6987 assert(isVarArg &&
"Only use custom memloc for vararg.");
6990 const unsigned OriginalValNo = VA.
getValNo();
6991 (
void)OriginalValNo;
6993 auto HandleCustomVecRegLoc = [&]() {
6994 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
6995 "Missing custom RegLoc.");
6998 "Unexpected Val type for custom RegLoc.");
7000 "ValNo mismatch between custom MemLoc and RegLoc.");
7011 HandleCustomVecRegLoc();
7012 HandleCustomVecRegLoc();
7016 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7018 "Only 2 custom RegLocs expected for 64-bit codegen.");
7019 HandleCustomVecRegLoc();
7020 HandleCustomVecRegLoc();
7063 if (Flags.isByVal() && VA.
isMemLoc()) {
7064 const unsigned Size =
7065 alignTo(Flags.getByValSize() ? Flags.getByValSize() : PtrByteSize,
7076 if (Flags.isByVal()) {
7082 if (Flags.getNonZeroByValAlign() > PtrByteSize)
7085 const unsigned StackSize =
alignTo(Flags.getByValSize(), PtrByteSize);
7094 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7096 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7109 CopyFrom.
getValue(1), dl, CopyFrom,
7119 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7122 "RegLocs should be for ByVal argument.");
7129 if (
Offset != StackSize) {
7131 "Expected MemLoc for remaining bytes.");
7132 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7163 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7165 unsigned CallerReservedArea =
7166 std::max(CCInfo.getNextStackOffset(), LinkageSize + MinParameterSaveArea);
7172 CallerReservedArea =
7181 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7182 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7184 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7185 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7186 const unsigned NumGPArgRegs =
array_lengthof(IsPPC64 ? GPR_64 : GPR_32);
7191 for (
unsigned GPRIndex =
7192 (CCInfo.getNextStackOffset() - LinkageSize) / PtrByteSize;
7193 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7196 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7197 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7209 if (!MemOps.
empty())
7215SDValue PPCTargetLowering::LowerCall_AIX(
7228 "Unexpected calling convention!");
7230 if (CFlags.IsPatchPoint)
7237 AIXCCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7245 const bool IsPPC64 = Subtarget.
isPPC64();
7247 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7248 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7249 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7257 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7258 const unsigned NumBytes = std::max(LinkageSize + MinParameterSaveAreaSize,
7259 CCInfo.getNextStackOffset());
7275 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7276 const unsigned ValNo = ArgLocs[
I].getValNo();
7280 if (Flags.isByVal()) {
7281 const unsigned ByValSize = Flags.getByValSize();
7289 auto GetLoad = [&](
EVT VT,
unsigned LoadOffset) {
7298 unsigned LoadOffset = 0;
7301 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7304 LoadOffset += PtrByteSize;
7307 "Unexpected location for pass-by-value argument.");
7311 if (LoadOffset == ByValSize)
7315 assert(ArgLocs[
I].getValNo() == ValNo &&
7316 "Expected additional location for by-value argument.");
7318 if (ArgLocs[
I].isMemLoc()) {
7319 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7324 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7330 CallSeqStart, MemcpyFlags, DAG, dl);
7339 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7340 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7341 "Unexpected register residue for by-value argument.");
7343 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7357 "Unexpected load emitted during handling of pass-by-value "
7365 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7400 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7408 const unsigned OriginalValNo = VA.
getValNo();
7410 unsigned LoadOffset = 0;
7411 auto HandleCustomVecRegLoc = [&]() {
7412 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7413 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7414 "Expected custom RegLoc.");
7417 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7423 LoadOffset += PtrByteSize;
7429 HandleCustomVecRegLoc();
7430 HandleCustomVecRegLoc();
7432 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7433 ArgLocs[
I].getValNo() == OriginalValNo) {
7435 "Only 2 custom RegLocs expected for 64-bit codegen.");
7436 HandleCustomVecRegLoc();
7437 HandleCustomVecRegLoc();
7455 "Unexpected register handling for calling convention.");
7461 "Custom register handling only expected for VarArg.");
7470 else if (
Arg.getValueType().getFixedSizeInBits() <
7479 "Unexpected custom register for argument!");
7500 if (!MemOpChains.
empty())
7505 if (CFlags.IsIndirect) {
7506 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7510 const unsigned TOCSaveOffset =
7526 for (
auto Reg : RegsToPass) {
7527 Chain = DAG.
getCopyToReg(Chain, dl, Reg.first, Reg.second, InFlag);
7531 const int SPDiff = 0;
7532 return FinishCall(CFlags, dl, DAG, RegsToPass, InFlag, Chain, CallSeqStart,
7533 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7537PPCTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
7542 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
7543 return CCInfo.CheckReturn(
7550PPCTargetLowering::LowerReturn(
SDValue Chain, CallingConv::ID CallConv,
7558 CCInfo.AnalyzeReturn(Outs,
7567 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7596 Flag = Chain.getValue(1);
7601 Flag = Chain.getValue(1);
7609 RetOps.push_back(Flag);
7615PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7620 EVT IntVT =
Op.getValueType();
7624 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7626 SDValue Ops[2] = {Chain, FPSIdx};
7640 bool isPPC64 = Subtarget.
isPPC64();
7641 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7661 bool isPPC64 = Subtarget.
isPPC64();
7682PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7684 bool isPPC64 = Subtarget.
isPPC64();
7718 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7719 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
7730 bool isPPC64 = Subtarget.
isPPC64();
7742 Op.getOperand(0),
Op.getOperand(1));
7749 Op.getOperand(0),
Op.getOperand(1));
7753 if (
Op.getValueType().isVector())
7754 return LowerVectorLoad(Op, DAG);
7757 "Custom lowering only for i1 loads");
7778 if (
Op.getOperand(1).getValueType().isVector())
7779 return LowerVectorStore(Op, DAG);
7782 "Custom lowering only for i1 stores");
7802 "Custom lowering only for i1 results");
7830 EVT TrgVT =
Op.getValueType();
7842 if (SrcSize > 256 ||
7854 if (SrcSize == 256) {
7865 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
7873 for (
unsigned i = 0; i < TrgNumElts; ++i)
7876 for (
unsigned i = 1; i <= TrgNumElts; ++i)
7880 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
7884 Op1 = DAG.
getNode(ISD::BITCAST,
DL, WideVT, Op1);
7885 Op2 = DAG.
getNode(ISD::BITCAST,
DL, WideVT, Op2);
7893 EVT ResVT =
Op.getValueType();
7894 EVT CmpVT =
Op.getOperand(0).getValueType();
7895 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
7896 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
7919 if (Subtarget.
hasP9Vector() && LHS == TV && RHS == FV) {
7950 if (LHS.getValueType() ==
MVT::f32)
7963 if (LHS.getValueType() ==
MVT::f32)
7972 if (LHS.getValueType() ==
MVT::f32)
8047 bool IsStrict = Op->isStrictFPOpcode();
8056 SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
8058 assert(Src.getValueType().isFloatingPoint());
8059 if (Src.getValueType() ==
MVT::f32) {
8064 Chain = Src.getValue(1);
8070 switch (Op.getSimpleValueType().SimpleTy) {
8078 "i64 FP_TO_UINT is supported only with FPCVT");
8084 {Chain, Src}, Flags);
8091void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8093 const SDLoc &dl)
const {
8097 bool IsStrict =
Op->isStrictFPOpcode();
8101 (IsSigned || Subtarget.
hasFPCVT());
8115 SDValue Ops[] = { Chain, Tmp, FIPtr };
8119 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8123 if (
Op.getValueType() ==
MVT::i32 && !i32Stack) {
8140 const SDLoc &dl)
const {
8143 if (
Op->isStrictFPOpcode())
8150 const SDLoc &dl)
const {
8151 bool IsStrict =
Op->isStrictFPOpcode();
8154 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8155 EVT SrcVT = Src.getValueType();
8156 EVT DstVT =
Op.getValueType();
8183 {Op.getOperand(0), Lo, Hi}, Flags);
8186 {Res.getValue(1), Res}, Flags);
8192 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8216 {Chain, Src, FltOfs}, Flags);
8220 {Chain, Val}, Flags);
8223 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8242 return LowerFP_TO_INTDirectMove(Op, DAG, dl);
8245 LowerFP_TO_INTForReuse(Op, RLI, DAG, dl);
8247 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8248 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8259bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8264 if (
Op->isStrictFPOpcode())
8273 Op.getOperand(0).getValueType())) {
8275 LowerFP_TO_INTForReuse(Op, RLI, DAG, dl);
8280 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8281 LD->isNonTemporal())
8283 if (
LD->getMemoryVT() != MemVT)
8293 RLI.Ptr =
LD->getBasePtr();
8294 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8296 "Non-pre-inc AM on PPC?");
8301 RLI.Chain =
LD->getChain();
8302 RLI.MPI =
LD->getPointerInfo();
8303 RLI.IsDereferenceable =
LD->isDereferenceable();
8304 RLI.IsInvariant =
LD->isInvariant();
8305 RLI.Alignment =
LD->getAlign();
8306 RLI.AAInfo =
LD->getAAInfo();
8307 RLI.Ranges =
LD->getRanges();
8309 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8317void PPCTargetLowering::spliceIntoChain(
SDValue ResChain,
8323 SDLoc dl(NewResChain);
8328 "A new TF really is required here");
8337bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &Op)
const {
8338 SDNode *Origin =
Op.getOperand(0).getNode();
8353 if (UI.getUse().get().getResNo() != 0)
8383 if (Op->isStrictFPOpcode()) {
8385 Chain = Op.getOperand(0);
8389 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8397 const SDLoc &dl)
const {
8400 "Invalid floating point type as target of conversion");
8402 "Int to FP conversions with direct moves require FPCVT");
8403 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8404 bool WordInt = Src.getSimpleValueType().SimpleTy ==
MVT::i32;
8426 for (
unsigned i = 1; i < NumConcat; ++i)
8433 const SDLoc &dl)
const {
8434 bool IsStrict =
Op->isStrictFPOpcode();
8435 unsigned Opc =
Op.getOpcode();
8436 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8439 "Unexpected conversion type");
8441 "Supports conversions to v2f64/v4f32 only.");
8456 for (
unsigned i = 0; i < WideNumElts; ++i)
8459 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8460 int SaveElts = FourEltRes ? 4 : 2;
8462 for (
int i = 0; i < SaveElts; i++)
8463 ShuffV[i * Stride] = i;
8465 for (
int i = 1; i <= SaveElts; i++)
8466 ShuffV[i * Stride - 1] = i - 1;
8474 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8475 EVT ExtVT = Src.getValueType();
8483 Extend = DAG.
getNode(ISD::BITCAST, dl, IntermediateVT, Arrange);
8487 {Op.getOperand(0), Extend}, Flags);
8489 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
8497 bool IsStrict =
Op->isStrictFPOpcode();
8498 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8505 EVT InVT = Src.getValueType();
8506 EVT OutVT =
Op.getValueType();
8509 return LowerINT_TO_FPVector(Op, DAG, dl);
8519 if (Src.getValueType() ==
MVT::i1) {
8531 if (Subtarget.
hasDirectMove() && directMoveIsProfitable(Op) &&
8533 return LowerINT_TO_FPDirectMove(Op, DAG, dl);
8536 "UINT_TO_FP is supported only with FPCVT");
8538 if (Src.getValueType() ==
MVT::i64) {
8592 if (canReuseLoadAddress(SINT,
MVT::i64, RLI, DAG)) {
8594 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8595 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8600 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8601 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8605 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8610 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8611 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8615 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8633 "Expected an i32 store");
8639 RLI.Alignment =
Align(4);
8643 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8644 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8649 Chain =
Bits.getValue(1);
8655 Chain =
FP.getValue(1);
8661 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8670 "Unhandled INT_TO_FP type in custom expander!");
8683 if (!(ReusingLoad = canReuseLoadAddress(Src,
MVT::i32, RLI, DAG))) {
8693 "Expected an i32 store");
8699 RLI.Alignment =
Align(4);
8704 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8705 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8711 spliceIntoChain(RLI.ResChain, Ld.
getValue(1), DAG);
8714 "i32->FP without LFIWAX supported only on PPC64");
8723 Chain, dl, Ext64, FIdx,
8737 Chain =
FP.getValue(1);
8742 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8773 EVT VT =
Op.getValueType();
8779 Chain =
MFFS.getValue(1);
8793 "Stack slot adjustment is valid only on big endian subtargets!");
8823 EVT VT =
Op.getValueType();
8827 VT ==
Op.getOperand(1).getValueType() &&
8847 SDValue OutOps[] = { OutLo, OutHi };
8852 EVT VT =
Op.getValueType();
8856 VT ==
Op.getOperand(1).getValueType() &&
8876 SDValue OutOps[] = { OutLo, OutHi };
8882 EVT VT =
Op.getValueType();
8885 VT ==
Op.getOperand(1).getValueType() &&
8905 SDValue OutOps[] = { OutLo, OutHi };
8912 EVT VT =
Op.getValueType();
8919 EVT AmtVT =
Z.getValueType();
8942 static const MVT VTys[] = {
8949 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
8954 EVT CanonicalVT = VTys[SplatSize-1];
8964 if (DestVT ==
MVT::Other) DestVT = Op.getValueType();
8998 for (
unsigned i = 0; i != 16; ++i)
9001 return DAG.
getNode(ISD::BITCAST, dl, VT, T);
9019 EVT VecVT = V->getValueType(0);
9026 bool IsSplat =
true;
9027 bool IsLoad =
false;
9033 if (V->isConstant())
9035 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9036 if (V->getOperand(i).isUndef())
9040 if (V->getOperand(i).getOpcode() == ISD::LOAD ||
9042 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
9044 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
9046 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD))
9050 if (V->getOperand(i) != Op0 ||
9051 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9054 return !(IsSplat && IsLoad);
9074 const SDValue *InputLoad = &Op;
9075 while (InputLoad->
getOpcode() == ISD::BITCAST)
9082 if (InputLoad->
getOpcode() != ISD::LOAD)
9092 APFloat APFloatToConvert = ArgAPFloat;
9093 bool LosesInfo =
true;
9098 ArgAPFloat = APFloatToConvert;
9120 APFloat APFloatToConvert = ArgAPFloat;
9121 bool LosesInfo =
true;
9125 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9134 EVT Ty = Op->getValueType(0);
9173 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9176 APInt APSplatBits, APSplatUndef;
9177 unsigned SplatBitSize;
9179 bool BVNIsConstantSplat =
9187 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9226 if (!BVNIsConstantSplat || SplatBitSize > 32) {
9233 const SDValue *InputLoad = &
Op.getOperand(0);
9238 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9239 unsigned ElementSize =
9242 assert(((ElementSize == 2 * MemorySize)
9246 "Unmatched element size and opcode!\n");
9251 unsigned NumUsesOfInputLD = 128 / ElementSize;
9253 if (BVInOp.isUndef())
9268 if (NumUsesOfInputLD == 1 &&
9280 Subtarget.
isISA3_1() && ElementSize <= 16)
9283 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9293 LD->getMemoryVT(),
LD->getMemOperand());
9314 unsigned SplatSize = SplatBitSize / 8;
9319 if (SplatBits == 0) {
9323 Op = DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(),
Z);
9335 Op.getValueType(), DAG, dl);
9347 int32_t SextVal= (int32_t(SplatBits << (32-SplatBitSize)) >>
9349 if (SextVal >= -16 && SextVal <= 15)
9362 if (SextVal >= -32 && SextVal <= 31) {
9371 if (VT ==
Op.getValueType())
9374 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), RetVal);
9380 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9390 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9394 static const signed char SplatCsts[] = {
9395 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9396 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9402 int i = SplatCsts[idx];
9406 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9409 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9411 static const unsigned IIDs[] = {
9412 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9413 Intrinsic::ppc_altivec_vslw
9416 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9420 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9422 static const unsigned IIDs[] = {
9423 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9424 Intrinsic::ppc_altivec_vsrw
9427 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9431 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9432 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9434 static const unsigned IIDs[] = {
9435 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9436 Intrinsic::ppc_altivec_vrlw
9439 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9443 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9449 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9455 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9470 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9471 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9472 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9488 if (LHSID == (1*9+2)*9+3)
return LHS;
9489 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9501 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9502 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9503 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9504 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9507 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9508 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9509 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9510 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9513 for (
unsigned i = 0; i != 16; ++i)
9514 ShufIdxs[i] = (i&3)+0;
9517 for (
unsigned i = 0; i != 16; ++i)
9518 ShufIdxs[i] = (i&3)+4;
9521 for (
unsigned i = 0; i != 16; ++i)
9522 ShufIdxs[i] = (i&3)+8;
9525 for (
unsigned i = 0; i != 16; ++i)
9526 ShufIdxs[i] = (i&3)+12;
9539 return DAG.
getNode(ISD::BITCAST, dl, VT, T);
9547 const unsigned BytesInVector = 16;
9552 unsigned ShiftElts = 0, InsertAtByte = 0;
9556 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
9557 0, 15, 14, 13, 12, 11, 10, 9};
9558 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
9559 1, 2, 3, 4, 5, 6, 7, 8};
9562 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
9574 bool FoundCandidate =
false;
9578 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
9581 for (
unsigned i = 0; i < BytesInVector; ++i) {
9582 unsigned CurrentElement =
Mask[i];
9585 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
9588 bool OtherElementsInOrder =
true;
9591 for (
unsigned j = 0; j < BytesInVector; ++j) {
9598 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
9599 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
9600 OtherElementsInOrder =
false;
9607 if (OtherElementsInOrder) {
9614 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
9615 : BigEndianShifts[CurrentElement & 0xF];
9616 Swap = CurrentElement < BytesInVector;
9618 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
9619 FoundCandidate =
true;
9624 if (!FoundCandidate)
9648 const unsigned NumHalfWords = 8;
9649 const unsigned BytesInVector = NumHalfWords * 2;
9658 unsigned ShiftElts = 0, InsertAtByte = 0;
9662 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
9663 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
9666 uint32_t OriginalOrderLow = 0x1234567;
9667 uint32_t OriginalOrderHigh = 0x89ABCDEF;
9670 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9671 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9672 Mask |= ((
uint32_t)(
N->getMaskElt(i * 2) / 2) << MaskShift);
9688 bool FoundCandidate =
false;
9691 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9692 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9694 uint32_t MaskOtherElts = ~(0xF << MaskShift);
9702 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
9703 TargetOrder = OriginalOrderLow;
9707 if (MaskOneElt == VINSERTHSrcElem &&
9708 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9709 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
9710 FoundCandidate =
true;
9716 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
9718 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9720 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
9721 : BigEndianShifts[MaskOneElt & 0x7];
9722 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
9723 Swap = MaskOneElt < NumHalfWords;
9724 FoundCandidate =
true;
9730 if (!FoundCandidate)
9765 auto ShuffleMask = SVN->
getMask();
9786 APInt APSplatValue, APSplatUndef;
9787 unsigned SplatBitSize;
9803 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
9804 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
9805 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
9807 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
9808 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
9809 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
9817 for (; SplatBitSize < 32; SplatBitSize <<= 1)
9818 SplatVal |= (SplatVal << SplatBitSize);
9833 "Only set v1i128 as custom, other type shouldn't reach here!");
9838 if (SHLAmt % 8 == 0) {
9839 std::array<int, 16>
Mask;
9840 std::iota(
Mask.begin(),
Mask.end(), 0);
9841 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
9870 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
9875 V1 =
Op.getOperand(0);
9876 V2 =
Op.getOperand(1);
9878 EVT VT =
Op.getValueType();
9881 unsigned ShiftElts, InsertAtByte;
9887 bool IsPermutedLoad =
false;
9889 if (InputLoad && Subtarget.
hasVSX() &&
V2.isUndef() &&
9899 if (IsPermutedLoad) {
9900 assert((isLittleEndian || IsFourByte) &&
9901 "Unexpected size for permuted load on big endian target");
9902 SplatIdx += IsFourByte ? 2 : 1;
9903 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
9904 "Splat of a value outside of the loaded memory");
9909 if ((IsFourByte && Subtarget.
hasP9Vector()) || !IsFourByte) {
9912 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
9914 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
9918 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
9934 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
9967 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
9968 return SplatInsertNode;
9973 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
9976 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
9980 if (Subtarget.
hasVSX() &&
9993 if (Subtarget.
hasVSX() &&
10026 if (Subtarget.
hasVSX()) {
10047 if (
V2.isUndef()) {
10071 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10092 unsigned PFIndexes[4];
10093 bool isFourElementShuffle =
true;
10094 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10096 unsigned EltNo = 8;
10097 for (
unsigned j = 0; j != 4; ++j) {
10098 if (PermMask[i * 4 + j] < 0)
10101 unsigned ByteSource = PermMask[i * 4 + j];
10102 if ((ByteSource & 3) != j) {
10103 isFourElementShuffle =
false;
10108 EltNo = ByteSource / 4;
10109 }
else if (EltNo != ByteSource / 4) {
10110 isFourElementShuffle =
false;
10114 PFIndexes[i] = EltNo;
10122 if (isFourElementShuffle) {
10124 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10125 PFIndexes[2] * 9 + PFIndexes[3];
10128 unsigned Cost = (PFEntry >> 30);
10148 if (
V2.isUndef())
V2 = V1;
10162 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10164 for (
unsigned j = 0; j != BytesPerElement; ++j)
10165 if (isLittleEndian)
10173 ShufflesHandledWithVPERM++;
10175 LLVM_DEBUG(
dbgs() <<
"Emitting a VPERM for the following shuffle:\n");
10177 LLVM_DEBUG(
dbgs() <<
"With the following permute control vector:\n");
10180 if (isLittleEndian)
10182 V2, V1, VPermMask);
10185 V1, V2, VPermMask);
10193 unsigned IntrinsicID =
10197 switch (IntrinsicID) {
10201 case Intrinsic::ppc_altivec_vcmpbfp_p:
10205 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10209 case Intrinsic::ppc_altivec_vcmpequb_p:
10213 case Intrinsic::ppc_altivec_vcmpequh_p:
10217 case Intrinsic::ppc_altivec_vcmpequw_p:
10221 case Intrinsic::ppc_altivec_vcmpequd_p:
10228 case Intrinsic::ppc_altivec_vcmpneb_p:
10229 case Intrinsic::ppc_altivec_vcmpneh_p:
10230 case Intrinsic::ppc_altivec_vcmpnew_p:
10231 case Intrinsic::ppc_altivec_vcmpnezb_p:
10232 case Intrinsic::ppc_altivec_vcmpnezh_p:
10233 case Intrinsic::ppc_altivec_vcmpnezw_p:
10235 switch (IntrinsicID) {
10238 case Intrinsic::ppc_altivec_vcmpneb_p:
10241 case Intrinsic::ppc_altivec_vcmpneh_p:
10244 case Intrinsic::ppc_altivec_vcmpnew_p:
10247 case Intrinsic::ppc_altivec_vcmpnezb_p:
10250 case Intrinsic::ppc_altivec_vcmpnezh_p:
10253 case Intrinsic::ppc_altivec_vcmpnezw_p:
10261 case Intrinsic::ppc_altivec_vcmpgefp_p:
10265 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10269 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10273 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10277 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10281 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10288 case Intrinsic::ppc_altivec_vcmpgtub_p:
10292 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10296 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10300 case Intrinsic::ppc_altivec_vcmpgtud_p:
10308 case Intrinsic::ppc_altivec_vcmpequq:
10309 case Intrinsic::ppc_altivec_vcmpgtsq:
10310 case Intrinsic::ppc_altivec_vcmpgtuq:
10313 switch (IntrinsicID) {
10316 case Intrinsic::ppc_altivec_vcmpequq:
10319 case Intrinsic::ppc_altivec_vcmpgtsq:
10322 case Intrinsic::ppc_altivec_vcmpgtuq:
10329 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10330 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10331 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10332 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10333 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10334 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10335 if (Subtarget.
hasVSX()) {
10336 switch (IntrinsicID) {
10337 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10340 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10343 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10346 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10349 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10352 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10362 case Intrinsic::ppc_altivec_vcmpbfp:
10365 case Intrinsic::ppc_altivec_vcmpeqfp:
10368 case Intrinsic::ppc_altivec_vcmpequb:
10371 case Intrinsic::ppc_altivec_vcmpequh:
10374 case Intrinsic::ppc_altivec_vcmpequw:
10377 case Intrinsic::ppc_altivec_vcmpequd:
10383 case Intrinsic::ppc_altivec_vcmpneb:
10384 case Intrinsic::ppc_altivec_vcmpneh:
10385 case Intrinsic::ppc_altivec_vcmpnew:
10386 case Intrinsic::ppc_altivec_vcmpnezb:
10387 case Intrinsic::ppc_altivec_vcmpnezh:
10388 case Intrinsic::ppc_altivec_vcmpnezw:
10390 switch (IntrinsicID) {
10393 case Intrinsic::ppc_altivec_vcmpneb:
10396 case Intrinsic::ppc_altivec_vcmpneh:
10399 case Intrinsic::ppc_altivec_vcmpnew:
10402 case Intrinsic::ppc_altivec_vcmpnezb:
10405 case Intrinsic::ppc_altivec_vcmpnezh:
10408 case Intrinsic::ppc_altivec_vcmpnezw:
10415 case Intrinsic::ppc_altivec_vcmpgefp:
10418 case Intrinsic::ppc_altivec_vcmpgtfp:
10421 case Intrinsic::ppc_altivec_vcmpgtsb:
10424 case Intrinsic::ppc_altivec_vcmpgtsh:
10427 case Intrinsic::ppc_altivec_vcmpgtsw:
10430 case Intrinsic::ppc_altivec_vcmpgtsd:
10436 case Intrinsic::ppc_altivec_vcmpgtub:
10439 case Intrinsic::ppc_altivec_vcmpgtuh:
10442 case Intrinsic::ppc_altivec_vcmpgtuw:
10445 case Intrinsic::ppc_altivec_vcmpgtud:
10451 case Intrinsic::ppc_altivec_vcmpequq_p:
10452 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10453 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10456 switch (IntrinsicID) {
10459 case Intrinsic::ppc_altivec_vcmpequq_p:
10462 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10465 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10479 unsigned IntrinsicID =
10484 switch (IntrinsicID) {
10485 case Intrinsic::thread_pointer:
10491 case Intrinsic::ppc_mma_disassemble_acc:
10492 case Intrinsic::ppc_vsx_disassemble_pair: {
10495 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
10500 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
10511 case Intrinsic::ppc_unpack_longdouble: {
10513 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
10514 "Argument of long double unpack must be 0 or 1!");
10517 Idx->getValueType(0)));
10520 case Intrinsic::ppc_compare_exp_lt:
10521 case Intrinsic::ppc_compare_exp_gt:
10522 case Intrinsic::ppc_compare_exp_eq:
10523 case Intrinsic::ppc_compare_exp_uo: {
10525 switch (IntrinsicID) {
10526 case Intrinsic::ppc_compare_exp_lt:
10529 case Intrinsic::ppc_compare_exp_gt:
10532 case Intrinsic::ppc_compare_exp_eq:
10535 case Intrinsic::ppc_compare_exp_uo:
10542 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
10543 Op.getOperand(1), Op.getOperand(2)),
10545 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
10546 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
10549 case Intrinsic::ppc_test_data_class_d:
10550 case Intrinsic::ppc_test_data_class_f: {
10551 unsigned CmprOpc = PPC::XSTSTDCDP;
10552 if (IntrinsicID == Intrinsic::ppc_test_data_class_f)
10553 CmprOpc = PPC::XSTSTDCSP;
10557 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
10560 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
10561 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
10564 case Intrinsic::ppc_fnmsub: {
10565 EVT VT =
Op.getOperand(1).getValueType();
10570 DAG.
getNode(ISD::FNEG, dl, VT,
Op.getOperand(3))));
10572 Op.getOperand(2),
Op.getOperand(3));
10574 case Intrinsic::ppc_convert_f128_to_ppcf128:
10575 case Intrinsic::ppc_convert_ppcf128_to_f128: {
10576 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
10577 ? RTLIB::CONVERT_PPCF128_F128
10578 : RTLIB::CONVERT_F128_PPCF128;
10579 MakeLibCallOptions CallOptions;
10580 std::pair<SDValue, SDValue>
Result =
10581 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
10585 case Intrinsic::ppc_maxfe:
10586 case Intrinsic::ppc_maxfl:
10587 case Intrinsic::ppc_maxfs:
10588 case Intrinsic::ppc_minfe:
10589 case Intrinsic::ppc_minfl:
10590 case Intrinsic::ppc_minfs: {
10591 EVT VT =
Op.getValueType();
10594 [VT](
const SDUse &
Use) { return Use.getValueType() == VT; }) &&
10595 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
10598 if (IntrinsicID == Intrinsic::ppc_minfe ||
10599 IntrinsicID == Intrinsic::ppc_minfl ||
10600 IntrinsicID == Intrinsic::ppc_minfs)
10602 unsigned I =
Op.getNumOperands() - 2, Cnt =
I;
10604 for (--
I; Cnt != 0; --Cnt,
I = (--
I == 0 ? (
Op.getNumOperands() - 1) :
I)) {
10622 Op.getOperand(1),
Op.getOperand(2),
10624 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Tmp);
10648 BitNo = 0; InvertBit =
false;
10651 BitNo = 0; InvertBit =
true;
10654 BitNo = 2; InvertBit =
false;
10657 BitNo = 2; InvertBit =
true;
10682 case Intrinsic::ppc_cfence: {
10683 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
10684 assert(Subtarget.
isPPC64() &&
"Only 64-bit is supported for now.");
10685 SDValue Val =
Op.getOperand(ArgStart + 1);
10715 int VectorIndex = 0;
10727 assert(
Op.getOpcode() == ISD::ATOMIC_CMP_SWAP &&
10728 "Expecting an atomic compare-and-swap here.");
10731 EVT MemVT = AtomicNode->getMemoryVT();
10749 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
10750 Ops.
push_back(AtomicNode->getOperand(i));
10762 EVT MemVT =
N->getMemoryVT();
10764 "Expect quadword atomic operations");
10766 unsigned Opc =
N->getOpcode();
10768 case ISD::ATOMIC_LOAD: {
10775 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
10778 Ops, MemVT,
N->getMemOperand());
10789 case ISD::ATOMIC_STORE: {
10805 N->getMemOperand());
10831 "Should only be called for ISD::INSERT_VECTOR_ELT");
10835 EVT VT =
Op.getValueType();
10858 BitcastLoad,
Op.getOperand(2));
10882 unsigned InsertAtElement =
C->getZExtValue();
10883 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
10885 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
10899 EVT VT =
Op.getValueType();
10908 "Type unsupported without MMA");
10910 "Type unsupported without paired vector support");
10915 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
10927 std::reverse(Loads.
begin(), Loads.
end());
10928 std::reverse(LoadChains.
begin(), LoadChains.
end());
10945 EVT StoreVT =
Value.getValueType();
10954 "Type unsupported without MMA");
10956 "Type unsupported without paired vector support");
10959 unsigned NumVecs = 2;
10964 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
10965 unsigned VecNum = Subtarget.
isLittleEndian() ? NumVecs - 1 - Idx : Idx;
10969 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
10984 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
11009 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
11027 for (
unsigned i = 0; i != 8; ++i) {
11028 if (isLittleEndian) {
11030 Ops[i*2+1] = 2*i+16;
11033 Ops[i*2+1] = 2*i+1+16;
11036 if (isLittleEndian)
11046 bool IsStrict =
Op->isStrictFPOpcode();
11047 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() ==
MVT::f128 &&
11057 assert(
Op.getOpcode() == ISD::FP_EXTEND &&
11058 "Should only be called for ISD::FP_EXTEND");
11075 "Node should have 2 operands with second one being a constant!");
11087 int DWord = Idx >> 1;
11107 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
11110 LD->getMemoryVT(),
LD->getMemOperand());
11120 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
11123 LD->getMemoryVT(),
LD->getMemOperand());
11134 switch (Op.getOpcode()) {
11136 case ISD::FPOW:
return lowerPow(Op, DAG);
11137 case ISD::FSIN:
return lowerSin(Op, DAG);
11138 case ISD::FCOS:
return lowerCos(Op, DAG);
11139 case ISD::FLOG:
return lowerLog(Op, DAG);
11140 case ISD::FLOG10:
return lowerLog10(Op, DAG);
11141 case ISD::FEXP:
return lowerExp(Op, DAG);
11149 case ISD::SETCC:
return LowerSETCC(Op, DAG);
11150 case ISD::INIT_TRAMPOLINE:
return LowerINIT_TRAMPOLINE(Op, DAG);
11151 case ISD::ADJUST_TRAMPOLINE:
return LowerADJUST_TRAMPOLINE(Op, DAG);
11153 case ISD::INLINEASM:
11154 case ISD::INLINEASM_BR:
return LowerINLINEASM(Op, DAG);
11156 case ISD::VASTART:
return LowerVASTART(Op, DAG);
11157 case ISD::VAARG:
return LowerVAARG(Op, DAG);
11158 case ISD::VACOPY:
return LowerVACOPY(Op, DAG);
11160 case ISD::STACKRESTORE:
return LowerSTACKRESTORE(Op, DAG);
11161 case ISD::DYNAMIC_STACKALLOC:
return LowerDYNAMIC_STACKALLOC(Op, DAG);
11162 case ISD::GET_DYNAMIC_AREA_OFFSET:
11163 return LowerGET_DYNAMIC_AREA_OFFSET(Op, DAG);
11170 case ISD::LOAD:
return LowerLOAD(Op, DAG);
11171 case ISD::STORE:
return LowerSTORE(Op, DAG);
11189 case ISD::FSHL:
return LowerFunnelShift(Op, DAG);
11190 case ISD::FSHR:
return LowerFunnelShift(Op, DAG);
11198 case ISD::MUL:
return LowerMUL(Op, DAG);
11199 case ISD::FP_EXTEND:
return LowerFP_EXTEND(Op, DAG);
11202 return LowerFP_ROUND(Op, DAG);
11203 case ISD::ROTL:
return LowerROTL(Op, DAG);
11208 case ISD::BITCAST:
return LowerBITCAST(Op, DAG);
11215 return LowerINTRINSIC_VOID(Op, DAG);
11217 return LowerBSWAP(Op, DAG);
11218 case ISD::ATOMIC_CMP_SWAP:
11219 return LowerATOMIC_CMP_SWAP(Op, DAG);
11220 case ISD::ATOMIC_STORE:
11221 return LowerATOMIC_LOAD_STORE(Op, DAG);
11229 switch (
N->getOpcode()) {
11231 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
11232 case ISD::ATOMIC_LOAD: {
11238 case ISD::READCYCLECOUNTER: {
11249 Intrinsic::loop_decrement)
11253 "Unexpected result type for CTR decrement intrinsic");
11255 N->getValueType(0));
11266 case Intrinsic::ppc_pack_longdouble:
11268 N->getOperand(2),
N->getOperand(1)));
11270 case Intrinsic::ppc_maxfe:
11271 case Intrinsic::ppc_minfe:
11272 case Intrinsic::ppc_fnmsub:
11273 case Intrinsic::ppc_convert_f128_to_ppcf128:
11283 EVT VT =
N->getValueType(0);
11298 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
11302 Results.push_back(LoweredValue);
11303 if (
N->isStrictFPOpcode())
11308 if (!
N->getValueType(0).isVector())
11322 case ISD::FP_EXTEND:
11335 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
11337 return Builder.CreateCall(Func, {});
11360 return Builder.CreateCall(
11362 Builder.GetInsertBlock()->getParent()->getParent(),
11363 Intrinsic::ppc_cfence, {Inst->getType()}),
11373 unsigned AtomicSize,
11374 unsigned BinOpcode,
11375 unsigned CmpOpcode,
11376 unsigned CmpPred)
const {
11380 auto LoadMnemonic = PPC::LDARX;
11381 auto StoreMnemonic = PPC::STDCX;
11382 switch (AtomicSize) {
11386 LoadMnemonic = PPC::LBARX;
11387 StoreMnemonic = PPC::STBCX;
11391 LoadMnemonic = PPC::LHARX;
11392 StoreMnemonic = PPC::STHCX;
11396 LoadMnemonic = PPC::LWARX;
11397 StoreMnemonic = PPC::STWCX;
11400 LoadMnemonic = PPC::LDARX;
11401 StoreMnemonic = PPC::STDCX;
11417 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
11421 F->insert(It, loop2MBB);
11422 F->insert(It, exitMBB);
11428 Register TmpReg = (!BinOpcode) ? incr :
11429 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
11430 : &PPC::GPRCRegClass);
11455 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
11461 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
11462 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
11463 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
11465 BuildMI(BB, dl,
TII->get(CmpOpcode), PPC::CR0)
11468 BuildMI(BB, dl,
TII->get(CmpOpcode), PPC::CR0)
11491 switch(
MI.getOpcode()) {
11495 return TII->isSignExtended(
MI);
11519 case PPC::EXTSB8_32_64:
11520 case PPC::EXTSB8_rec:
11521 case PPC::EXTSB_rec:
11524 case PPC::EXTSH8_32_64:
11525 case PPC::EXTSH8_rec:
11526 case PPC::EXTSH_rec:
11528 case PPC::EXTSWSLI:
11529 case PPC::EXTSWSLI_32_64:
11530 case PPC::EXTSWSLI_32_64_rec:
11531 case PPC::EXTSWSLI_rec:
11532 case PPC::EXTSW_32:
11533 case PPC::EXTSW_32_64:
11534 case PPC::EXTSW_32_64_rec:
11535 case PPC::EXTSW_rec:
11538 case PPC::SRAWI_rec:
11539 case PPC::SRAW_rec:
11548 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
11561 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
11562 Register ValueReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
11563 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
11564 .
addReg(
MI.getOperand(3).getReg());
11565 MI.getOperand(3).setReg(ValueReg);
11576 bool is64bit = Subtarget.
isPPC64();
11578 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
11589 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
11593 F->insert(It, loop2MBB);
11594 F->insert(It, exitMBB);
11600 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
11603 Register PtrReg = RegInfo.createVirtualRegister(RC);
11604 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
11606 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
11607 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
11608 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
11609 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
11610 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
11611 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
11612 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
11613 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
11614 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
11615 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
11618 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
11645 if (ptrA != ZeroReg) {
11646 Ptr1Reg = RegInfo.createVirtualRegister(RC);
11647 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
11655 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
11656 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
11659 .
addImm(is8bit ? 28 : 27);
11660 if (!isLittleEndian)
11661 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
11663 .
addImm(is8bit ? 24 : 16);
11665 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
11670 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
11680 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
11684 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
11689 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
11693 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
11696 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
11703 Register SReg = RegInfo.createVirtualRegister(GPRC);
11707 unsigned ValueReg = SReg;
11708 unsigned CmpReg = Incr2Reg;
11709 if (CmpOpcode == PPC::CMPW) {
11710 ValueReg = RegInfo.createVirtualRegister(GPRC);
11711 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
11714 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
11715 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
11717 ValueReg = ValueSReg;
11720 BuildMI(BB, dl,
TII->get(CmpOpcode), PPC::CR0)
11751 .
addImm(is8bit ? 24 : 16)
11772 Register DstReg =
MI.getOperand(0).getReg();
11775 Register mainDstReg =
MRI.createVirtualRegister(RC);
11776 Register restoreDstReg =
MRI.createVirtualRegister(RC);
11780 "Invalid Pointer Size!");
11828 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
11829 Register BufReg =
MI.getOperand(1).getReg();
11844 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
11846 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
11849 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
11872 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
11893 TII->get(PPC::PHI), DstReg)
11897 MI.eraseFromParent();
11912 "Invalid Pointer Size!");
11915 (PVT ==
MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
11918 unsigned FP = (PVT ==
MVT::i64) ? PPC::X31 : PPC::R31;
11919 unsigned SP = (PVT ==
MVT::i64) ? PPC::X1 : PPC::R1;
11933 Register BufReg =
MI.getOperand(0).getReg();
11999 MI.eraseFromParent();
12015 "Unexpected stack alignment");
12018 unsigned StackProbeSize = 4096;
12025 StackProbeSize &= ~(StackAlign - 1);
12026 return StackProbeSize ? StackProbeSize : StackAlign;
12038 const bool isPPC64 = Subtarget.
isPPC64();
12070 MF->
insert(MBBIter, TestMBB);
12071 MF->
insert(MBBIter, BlockMBB);
12072 MF->
insert(MBBIter, TailMBB);
12077 Register DstReg =
MI.getOperand(0).getReg();
12078 Register NegSizeReg =
MI.getOperand(1).getReg();
12079 Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
12080 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12081 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12082 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12088 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
12090 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
12096 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
12097 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
12099 .
addDef(ActualNegSizeReg)
12101 .
add(
MI.getOperand(2))
12102 .
add(
MI.getOperand(3));
12108 .
addReg(ActualNegSizeReg);
12111 int64_t NegProbeSize = -(int64_t)ProbeSize;
12113 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12115 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12117 .
addImm(NegProbeSize >> 16);
12121 .
addImm(NegProbeSize & 0xFFFF);
12128 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12130 .
addReg(ActualNegSizeReg)
12132 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12136 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12139 .
addReg(ActualNegSizeReg);
12148 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
12149 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
12163 BuildMI(BlockMBB,
DL,
TII->get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
12174 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12176 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
12177 MaxCallFrameSizeReg)
12178 .
add(
MI.getOperand(2))
12179 .
add(
MI.getOperand(3));
12180 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
12182 .
addReg(MaxCallFrameSizeReg);
12191 MI.eraseFromParent();
12193 ++NumDynamicAllocaProbed;
12200 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
12201 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
12203 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
12216 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
12217 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
12219 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
12220 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
12234 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12235 MI.getOpcode() == PPC::SELECT_CC_I8 ||
MI.getOpcode() == PPC::SELECT_I4 ||
12236 MI.getOpcode() == PPC::SELECT_I8) {
12238 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12239 MI.getOpcode() == PPC::SELECT_CC_I8)
12243 Cond.push_back(
MI.getOperand(1));
12246 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
12247 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
12248 }
else if (
MI.getOpcode() == PPC::SELECT_CC_F4 ||
12249 MI.getOpcode() == PPC::SELECT_CC_F8 ||
12250 MI.getOpcode() == PPC::SELECT_CC_F16 ||
12251 MI.getOpcode() == PPC::SELECT_CC_VRRC ||
12252 MI.getOpcode() == PPC::SELECT_CC_VSFRC ||
12253 MI.getOpcode() == PPC::SELECT_CC_VSSRC ||
12254 MI.getOpcode() == PPC::SELECT_CC_VSRC ||
12255 MI.getOpcode() == PPC::SELECT_CC_SPE4 ||
12256 MI.getOpcode() == PPC::SELECT_CC_SPE ||
12257 MI.getOpcode() == PPC::SELECT_F4 ||
12258 MI.getOpcode() == PPC::SELECT_F8 ||
12259 MI.getOpcode() == PPC::SELECT_F16 ||
12260 MI.getOpcode() == PPC::SELECT_SPE ||
12261 MI.getOpcode() == PPC::SELECT_SPE4 ||
12262 MI.getOpcode() == PPC::SELECT_VRRC ||
12263 MI.getOpcode() == PPC::SELECT_VSFRC ||
12264 MI.getOpcode() == PPC::SELECT_VSSRC ||
12265 MI.getOpcode() == PPC::SELECT_VSRC) {
12280 F->insert(It, copy0MBB);
12281 F->insert(It, sinkMBB);
12292 if (
MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8 ||
12293 MI.getOpcode() == PPC::SELECT_F4 ||
MI.getOpcode() == PPC::SELECT_F8 ||
12294 MI.getOpcode() == PPC::SELECT_F16 ||
12295 MI.getOpcode() == PPC::SELECT_SPE4 ||
12296 MI.getOpcode() == PPC::SELECT_SPE ||
12297 MI.getOpcode() == PPC::SELECT_VRRC ||
12298 MI.getOpcode() == PPC::SELECT_VSFRC ||
12299 MI.getOpcode() == PPC::SELECT_VSSRC ||
12300 MI.getOpcode() == PPC::SELECT_VSRC) {
12302 .
addReg(
MI.getOperand(1).getReg())
12305 unsigned SelectPred =
MI.getOperand(4).getImm();
12308 .
addReg(
MI.getOperand(1).getReg())
12325 .
addReg(
MI.getOperand(3).getReg())
12327 .
addReg(
MI.getOperand(2).getReg())
12329 }
else if (
MI.getOpcode() == PPC::ReadTB) {
12345 F->insert(It, readMBB);
12346 F->insert(It, sinkMBB);
12357 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
12365 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
12367 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
12377 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
12379 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
12381 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
12383 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
12386 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
12388 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
12390 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
12392 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
12395 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
12397 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
12399 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
12401 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
12404 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
12406 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
12408 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
12410 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
12413 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
12415 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
12417 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
12419 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
12422 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
12424 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
12426 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
12428 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
12431 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
12433 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
12435 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
12437 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
12440 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
12442 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
12444 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
12446 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
12449 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
12451 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
12453 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
12455 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
12458 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
12460 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
12462 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
12464 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
12467 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
12469 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
12471 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
12473 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
12475 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
12476 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
12478 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
12480 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
12481 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
12483 auto LoadMnemonic = PPC::LDARX;
12484 auto StoreMnemonic = PPC::STDCX;
12485 switch (
MI.getOpcode()) {
12488 case PPC::ATOMIC_CMP_SWAP_I8:
12489 LoadMnemonic = PPC::LBARX;
12490 StoreMnemonic = PPC::STBCX;
12493 case PPC::ATOMIC_CMP_SWAP_I16:
12494 LoadMnemonic = PPC::LHARX;
12495 StoreMnemonic = PPC::STHCX;
12498 case PPC::ATOMIC_CMP_SWAP_I32:
12499 LoadMnemonic = PPC::LWARX;
12500 StoreMnemonic = PPC::STWCX;
12502 case PPC::ATOMIC_CMP_SWAP_I64:
12503 LoadMnemonic = PPC::LDARX;
12504 StoreMnemonic = PPC::STDCX;
12510 Register oldval =
MI.getOperand(3).getReg();
12511 Register newval =
MI.getOperand(4).getReg();
12519 F->insert(It, loop2MBB);
12520 F->insert(It, midMBB);
12521 F->insert(It, exitMBB);
12544 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), PPC::CR0)
12577 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
12578 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
12582 bool is64bit = Subtarget.
isPPC64();
12584 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
12589 Register oldval =
MI.getOperand(3).getReg();
12590 Register newval =
MI.getOperand(4).getReg();
12598 F->insert(It, loop2MBB);
12599 F->insert(It, midMBB);
12600 F->insert(It, exitMBB);
12607 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12610 Register PtrReg = RegInfo.createVirtualRegister(RC);
12611 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
12613 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
12614 Register NewVal2Reg = RegInfo.createVirtualRegister(GPRC);
12615 Register NewVal3Reg = RegInfo.createVirtualRegister(GPRC);
12616 Register OldVal2Reg = RegInfo.createVirtualRegister(GPRC);
12617 Register OldVal3Reg = RegInfo.createVirtualRegister(GPRC);
12618 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
12619 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
12620 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
12621 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
12622 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
12623 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
12625 Register TmpReg = RegInfo.createVirtualRegister(GPRC);
12626 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
12659 if (ptrA != ZeroReg) {
12660 Ptr1Reg = RegInfo.createVirtualRegister(RC);
12661 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
12670 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
12671 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
12674 .
addImm(is8bit ? 28 : 27);
12675 if (!isLittleEndian)
12676 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
12678 .
addImm(is8bit ? 24 : 16);
12680 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
12685 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
12690 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
12693 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
12700 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
12704 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
12707 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
12710 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
12715 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
12721 BuildMI(BB, dl,
TII->get(PPC::CMPW), PPC::CR0)
12732 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
12763 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
12773 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
12788 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
12796 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
12797 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
12798 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
12799 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
12800 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
12801 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
12804 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
12805 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
12808 Register Dest = RegInfo.createVirtualRegister(
12809 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
12813 .
addReg(
MI.getOperand(1).getReg())
12816 MI.getOperand(0).getReg())
12817 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
12818 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
12821 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
12824 MI.getOperand(0).getReg())
12826 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
12828 unsigned Imm =
MI.getOperand(1).getImm();
12831 MI.getOperand(0).getReg())
12833 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
12835 Register OldFPSCRReg =
MI.getOperand(0).getReg();
12838 if (
MRI.use_empty(OldFPSCRReg))
12839 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
12841 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
12852 unsigned Mode =
MI.getOperand(1).getImm();
12853 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
12857 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
12860 }
else if (
MI.getOpcode() == PPC::SETRND) {
12868 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
12870 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
12874 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
12877 if (RC == &PPC::F8RCRegClass) {
12879 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
12880 "Unsupported RegClass.");
12882 StoreOp = PPC::STFD;
12886 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
12887 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
12888 "Unsupported RegClass.");
12921 Register OldFPSCRReg =
MI.getOperand(0).getReg();
12924 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
12936 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
12938 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
12940 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
12941 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
12946 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
12947 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
12952 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
12953 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
12959 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
12960 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
12969 }
else if (
MI.getOpcode() == PPC::SETFLM) {
12973 Register OldFPSCRReg =
MI.getOperand(0).getReg();
12974 if (
MRI.use_empty(OldFPSCRReg))
12975 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
12977 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
12980 Register NewFPSCRReg =
MI.getOperand(1).getReg();
12986 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
12987 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
12989 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
12996 .
addUse(Src, 0, PPC::sub_gp8_x1);
12999 .
addUse(Src, 0, PPC::sub_gp8_x0);
13000 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
13001 MI.getOpcode() == PPC::STQX_PSEUDO) {
13007 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
13013 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
13014 :
TII->get(PPC::STQ))
13022 MI.eraseFromParent();
13035 int RefinementSteps = Subtarget.
hasRecipPrec() ? 1 : 3;
13038 return RefinementSteps;
13044 EVT VT =
Op.getValueType();
13071PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
13074 EVT VT =
Op.getValueType();
13083 int Enabled,
int &RefinementSteps,
13084 bool &UseOneConstNR,
13085 bool Reciprocal)
const {
13104 int &RefinementSteps)
const {
13117unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
13145 Base = Loc.getOperand(0);
13155 unsigned Bytes,
int Dist,
13169 if (FS != BFS || FS != (
int)Bytes)
return false;
13173 SDValue Base1 = Loc, Base2 = BaseLoc;
13174 int64_t Offset1 = 0, Offset2 = 0;
13177 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
13187 if (isGA1 && isGA2 && GV1 == GV2)
13188 return Offset1 == (Offset2 + Dist*Bytes);
13195 unsigned Bytes,
int Dist,
13198 EVT VT = LS->getMemoryVT();
13199 SDValue Loc = LS->getBasePtr();
13206 default:
return false;
13207 case Intrinsic::ppc_altivec_lvx:
13208 case Intrinsic::ppc_altivec_lvxl:
13209 case Intrinsic::ppc_vsx_lxvw4x:
13210 case Intrinsic::ppc_vsx_lxvw4x_be:
13213 case Intrinsic::ppc_vsx_lxvd2x:
13214 case Intrinsic::ppc_vsx_lxvd2x_be:
13217 case Intrinsic::ppc_altivec_lvebx:
13220 case Intrinsic::ppc_altivec_lvehx:
13223 case Intrinsic::ppc_altivec_lvewx:
13234 default:
return false;
13235 case Intrinsic::ppc_altivec_stvx:
13236 case Intrinsic::ppc_altivec_stvxl:
13237 case Intrinsic::ppc_vsx_stxvw4x:
13240 case Intrinsic::ppc_vsx_stxvd2x:
13243 case Intrinsic::ppc_vsx_stxvw4x_be:
13246 case Intrinsic::ppc_vsx_stxvd2x_be:
13249 case Intrinsic::ppc_altivec_stvebx:
13252 case Intrinsic::ppc_altivec_stvehx:
13255 case Intrinsic::ppc_altivec_stvewx:
13272 SDValue Chain = LD->getChain();
13273 EVT VT = LD->getMemoryVT();
13282 while (!Queue.empty()) {
13283 SDNode *ChainNext = Queue.pop_back_val();
13284 if (!Visited.
insert(ChainNext).second)
13291 if (!Visited.
count(ChainLD->getChain().getNode()))
13292 Queue.push_back(ChainLD->getChain().getNode());
13294 for (
const SDUse &O : ChainNext->
ops())
13295 if (!Visited.
count(O.getNode()))
13296 Queue.push_back(O.getNode());
13298 LoadRoots.
insert(ChainNext);
13310 IE = LoadRoots.
end();
I != IE; ++
I) {
13311 Queue.push_back(*
I);
13313 while (!Queue.empty()) {
13314 SDNode *LoadRoot = Queue.pop_back_val();
13315 if (!Visited.
insert(LoadRoot).second)
13327 Queue.push_back(U);
13360 auto Final = Shifted;
13371 DAGCombinerInfo &DCI)
const {
13379 if (!DCI.isAfterLegalizeDAG())
13389 auto OpSize =
N->getOperand(0).getValueSizeInBits();
13393 if (OpSize <
Size) {
13411 DAGCombinerInfo &DCI)
const {
13429 if (
N->getOperand(0).getValueType() !=
MVT::i32 &&
13430 N->getOperand(0).getValueType() !=
MVT::i64)
13440 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
13451 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
13474 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
13475 N->getOperand(0).getOpcode() !=
ISD::OR &&
13476 N->getOperand(0).getOpcode() !=
ISD::XOR &&
13486 N->getOperand(1).getOpcode() !=
ISD::AND &&
13487 N->getOperand(1).getOpcode() !=
ISD::OR &&
13488 N->getOperand(1).getOpcode() !=
ISD::XOR &&
13501 for (
unsigned i = 0; i < 2; ++i) {
13505 N->getOperand(i).getOperand(0).getValueType() ==
MVT::i1) ||
13517 while (!BinOps.
empty()) {
13525 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
13559 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
13563 for (
const SDNode *
User : Inputs[i].getNode()->uses()) {
13583 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
13584 for (
const SDNode *
User : PromOps[i].getNode()->uses()) {
13605 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
13614 std::list<HandleSDNode> PromOpHandles;
13615 for (
auto &PromOp : PromOps)
13616 PromOpHandles.emplace_back(PromOp);
13623 while (!PromOpHandles.empty()) {
13625 PromOpHandles.pop_back();
13634 PromOpHandles.emplace_front(PromOp);
13648 default:
C = 0;
break;
13661 PromOpHandles.emplace_front(PromOp);
13669 for (
unsigned i = 0; i < 2; ++i)
13679 return N->getOperand(0);
13687 DAGCombinerInfo &DCI)
const {
13713 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
13714 N->getOperand(0).getOpcode() !=
ISD::OR &&
13715 N->getOperand(0).getOpcode() !=
ISD::XOR &&
13726 while (!BinOps.
empty()) {
13734 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
13765 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
13769 for (
SDNode *
User : Inputs[i].getNode()->uses()) {
13777 SelectTruncOp[0].
insert(std::make_pair(
User,
13781 SelectTruncOp[0].
insert(std::make_pair(
User,
13784 SelectTruncOp[1].
insert(std::make_pair(
User,
13790 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
13791 for (
SDNode *
User : PromOps[i].getNode()->uses()) {
13799 SelectTruncOp[0].
insert(std::make_pair(
User,
13803 SelectTruncOp[0].
insert(std::make_pair(
User,
13806 SelectTruncOp[1].
insert(std::make_pair(
User,
13812 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
13813 bool ReallyNeedsExt =
false;
13817 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
13822 Inputs[i].getOperand(0).getValueSizeInBits();
13823 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
13828 OpBits-PromBits))) ||
13831 (OpBits-(PromBits-1)))) {
13832 ReallyNeedsExt =
true;
13840 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
13847 SDValue InSrc = Inputs[i].getOperand(0);
13861 std::list<HandleSDNode> PromOpHandles;
13862 for (
auto &PromOp : PromOps)
13863 PromOpHandles.emplace_back(PromOp);
13869 while (!PromOpHandles.empty()) {
13871 PromOpHandles.pop_back();
13875 default:
C = 0;
break;
13888 PromOpHandles.emplace_front(PromOp);
13898 (SelectTruncOp[1].count(PromOp.
getNode()) &&
13900 PromOpHandles.emplace_front(PromOp);
13909 for (
unsigned i = 0; i < 2; ++i) {
13927 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
13928 if (SI0 != SelectTruncOp[0].end())
13930 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
13931 if (SI1 != SelectTruncOp[1].end())
13940 if (!ReallyNeedsExt)
13941 return N->getOperand(0);
13948 N->getValueSizeInBits(0), PromBits),
13949 dl,
N->getValueType(0)));
13952 "Invalid extension type");
13955 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
13963 DAGCombinerInfo &DCI)
const {
13965 "Should be called with a SETCC node");
13983 EVT VT =
N->getValueType(0);
13984 EVT OpVT = LHS.getValueType();
13990 return DAGCombineTruncBoolExt(
N, DCI);
14009combineElementTruncationToVectorTruncation(
SDNode *
N,
14010 DAGCombinerInfo &DCI)
const {
14012 "Should be called with a BUILD_VECTOR node");
14019 "The input operand must be an fp-to-int conversion.");
14028 bool IsSplat =
true;
14033 EVT TargetVT =
N->getValueType(0);
14034 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14039 if (NextConversion != FirstConversion)
14047 if (
N->getOperand(i) != FirstInput)
14058 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14059 SDValue In =
N->getOperand(i).getOperand(0);
14084 return DAG.
getNode(Opcode, dl, TargetVT, BV);
14097 "Should be called with a BUILD_VECTOR node");
14102 if (!
N->getValueType(0).getVectorElementType().isByteSized())
14105 bool InputsAreConsecutiveLoads =
true;
14106 bool InputsAreReverseConsecutive =
true;
14107 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
14109 bool IsRoundOfExtLoad =
false;
14114 IsRoundOfExtLoad = LD->getExtensionType() ==
ISD::EXTLOAD;
14117 if ((!IsRoundOfExtLoad && FirstInput.
getOpcode() != ISD::LOAD) ||
14118 N->getNumOperands() == 1)
14121 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
14123 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
14126 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
14128 if (NextInput.
getOpcode() != ISD::LOAD)
14132 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
14141 InputsAreConsecutiveLoads =
false;
14143 InputsAreReverseConsecutive =
false;
14146 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
14150 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
14151 "The loads cannot be both consecutive and reverse consecutive.");
14154 IsRoundOfExtLoad ? FirstInput.
getOperand(0) : FirstInput;
14156 IsRoundOfExtLoad ?
N->getOperand(
N->getNumOperands()-1).getOperand(0) :
14157 N->getOperand(
N->getNumOperands()-1);
14161 if (InputsAreConsecutiveLoads) {
14162 assert(LD1 &&
"Input needs to be a LoadSDNode.");
14167 if (InputsAreReverseConsecutive) {
14168 assert(LDL &&
"Input needs to be a LoadSDNode.");
14170 DAG.
getLoad(
N->getValueType(0), dl, LDL->getChain(), LDL->getBasePtr(),
14171 LDL->getPointerInfo(), LDL->getAlign());
14173 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
14177 DAG.
getUNDEF(
N->getValueType(0)), Ops);
14190 unsigned NumElems = Input.getValueType().getVectorNumElements();
14196 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14198 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
14200 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
14201 CorrectElems = CorrectElems >> 8;
14202 Elems = Elems >> 8;
14207 DAG.
getUNDEF(Input.getValueType()), ShuffleMask);
14209 EVT VT =
N->getValueType(0);
14213 Input.getValueType().getVectorElementType(),
14247 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
14256 SDValue Extract = Op.getOperand(0);
14267 if (Input && Input != Extract.
getOperand(0))
14273 Elems = Elems << 8;
14282 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14283 if (!isSExtOfVecExtract(
N->getOperand(i))) {
14290 int TgtElemArrayIdx;
14292 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
14293 if (InputSize + OutputSize == 40)
14294 TgtElemArrayIdx = 0;
14295 else if (InputSize + OutputSize == 72)
14296 TgtElemArrayIdx = 1;
14297 else if (InputSize + OutputSize == 48)
14298 TgtElemArrayIdx = 2;
14299 else if (InputSize + OutputSize == 80)
14300 TgtElemArrayIdx = 3;
14301 else if (InputSize + OutputSize == 96)
14302 TgtElemArrayIdx = 4;
14306 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
14308 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
14309 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
14310 if (Elems != CorrectElems) {
14336 EVT MemoryType = LD->getMemoryVT();
14340 bool ValidLDType = MemoryType ==
MVT::i8 || MemoryType ==
MVT::i16 ||
14344 if (!ValidLDType ||
14350 LD->getChain(), LD->getBasePtr(),
14355 LoadOps, MemoryType, LD->getMemOperand());
14359 DAGCombinerInfo &DCI)
const {
14361 "Should be called with a BUILD_VECTOR node");
14366 if (!Subtarget.
hasVSX())
14374 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
14389 if (Subtarget.
hasP9Altivec() && !DCI.isBeforeLegalize()) {
14415 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
14426 if (!Ext1Op || !Ext2Op)
14435 if (FirstElem == 0 && SecondElem == 1)
14437 else if (FirstElem == 2 && SecondElem == 3)
14450 DAGCombinerInfo &DCI)
const {
14453 "Need an int -> FP conversion node here");
14466 if (!
Op.getOperand(0).getValueType().isSimple())
14468 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(
MVT::i1) ||
14469 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(
MVT::i64))
14472 SDValue FirstOperand(
Op.getOperand(0));
14473 bool SubWordLoad = FirstOperand.getOpcode() == ISD::LOAD &&
14474 (FirstOperand.getValueType() ==
MVT::i8 ||
14475 FirstOperand.getValueType() ==
MVT::i16);
14478 bool DstDouble =
Op.getValueType() ==
MVT::f64;
14479 unsigned ConvOp =
Signed ?
14486 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
14489 Ops,
MVT::i8, LDN->getMemOperand());
14493 SDValue ExtOps[] = { Ld, WidthConst };
14505 if (
Op.getOperand(0).getValueType() ==
MVT::i32)
14509 "UINT_TO_FP is supported only with FPCVT");
14527 SDValue Src =
Op.getOperand(0).getOperand(0);
14528 if (Src.getValueType() ==
MVT::f32) {
14530 DCI.AddToWorklist(Src.getNode());
14531 }
else if (Src.getValueType() !=
MVT::f64) {
14546 DCI.AddToWorklist(
FP.getNode());
14570 switch (
N->getOpcode()) {
14575 Chain = LD->getChain();
14576 Base = LD->getBasePtr();
14577 MMO = LD->getMemOperand();
14596 MVT VecTy =
N->getValueType(0).getSimpleVT();
14604 Chain = Load.getValue(1);
14637 switch (
N->getOpcode()) {
14642 Chain = ST->getChain();
14643 Base = ST->getBasePtr();
14644 MMO = ST->getMemOperand();
14664 SDValue Src =
N->getOperand(SrcOpnd);
14665 MVT VecTy = Src.getValueType().getSimpleVT();
14680 StoreOps, VecTy, MMO);
14687 DAGCombinerInfo &DCI)
const {
14691 unsigned Opcode =
N->getOperand(1).getOpcode();
14694 &&
"Not a FP_TO_INT Instruction!");
14697 EVT Op1VT =
N->getOperand(1).getValueType();
14704 bool ValidTypeForStoreFltAsInt =
14718 DCI.AddToWorklist(Val.
getNode());
14724 PPCISD::FP_TO_UINT_IN_VSR;
14726 Val = DAG.
getNode(ConvOpcode,
14728 DCI.AddToWorklist(Val.
getNode());
14741 DCI.AddToWorklist(Val.
getNode());
14748 bool PrevElemFromFirstVec = Mask[0] < NumElts;
14749 for (
int i = 1, e = Mask.size(); i < e; i++) {
14750 if (PrevElemFromFirstVec && Mask[i] < NumElts)
14752 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
14754 PrevElemFromFirstVec = !PrevElemFromFirstVec;
14765 for (
int i = 0, e = Op.getNumOperands(); i < e; i++) {
14766 FirstOp = Op.getOperand(i);
14772 for (
int i = 1, e = Op.getNumOperands(); i < e; i++)
14773 if (Op.getOperand(i) != FirstOp && !Op.getOperand(i).isUndef())
14781 if (Op.getOpcode() != ISD::BITCAST)
14783 Op = Op.getOperand(0);
14798 int LHSMaxIdx,
int RHSMinIdx,
14799 int RHSMaxIdx,
int HalfVec,
14800 unsigned ValidLaneWidth,
14802 for (
int i = 0, e = ShuffV.
size(); i < e; i++) {
14803 int Idx = ShuffV[i];
14804 if ((Idx >= 0 && Idx < LHSMaxIdx) || (Idx >= RHSMinIdx && Idx < RHSMaxIdx))
14806 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - ValidLaneWidth;
14817 SDLoc dl(OrigSToV);
14820 "Expecting a SCALAR_TO_VECTOR here");
14833 "Cannot produce a permuted scalar_to_vector for one element vector");
14835 unsigned ResultInElt = NumElts / 2;
14862 int NumElts = LHS.getValueType().getVectorNumElements();
14891 if (SToVLHS || SToVRHS) {
14898 if (SToVLHS && SToVRHS &&
14905 int NumEltsOut = ShuffV.
size();
14910 unsigned ValidLaneWidth =
14912 LHS.getValueType().getScalarSizeInBits()
14914 RHS.getValueType().getScalarSizeInBits();
14918 int LHSMaxIdx = -1;
14919 int RHSMinIdx = -1;
14920 int RHSMaxIdx = -1;
14921 int HalfVec = LHS.getValueType().getVectorNumElements() / 2;
14933 LHSMaxIdx = NumEltsOut / NumEltsIn;
14936 SToVLHS = DAG.
getBitcast(LHS.getValueType(), SToVLHS);
14942 RHSMinIdx = NumEltsOut;
14943 RHSMaxIdx = NumEltsOut / NumEltsIn + RHSMinIdx;
14946 SToVRHS = DAG.
getBitcast(RHS.getValueType(), SToVRHS);
14956 HalfVec, ValidLaneWidth, Subtarget);
14982 if (IsLittleEndian) {
14985 if (Mask[0] < NumElts)
14986 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
14989 ShuffV[i] = (ShuffV[i - 1] + NumElts);
14994 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
14997 ShuffV[i] = (ShuffV[i + 1] + NumElts);
15002 if (Mask[0] < NumElts)
15003 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
15006 ShuffV[i] = ShuffV[i + 1] - NumElts;
15011 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
15014 ShuffV[i] = ShuffV[i - 1] - NumElts;
15024 if (IsLittleEndian)
15033 DAGCombinerInfo &DCI)
const {
15035 "Not a reverse memop pattern!");
15040 auto I =
Mask.rbegin();
15041 auto E =
Mask.rend();
15043 for (;
I !=
E; ++
I) {
15063 if(!IsElementReverse(SVN))
15066 if (LSBase->
getOpcode() == ISD::LOAD) {
15082 if (LSBase->
getOpcode() == ISD::STORE) {
15104 switch (
N->getOpcode()) {
15107 return combineADD(
N, DCI);
15109 return combineSHL(
N, DCI);
15111 return combineSRA(
N, DCI);
15113 return combineSRL(
N, DCI);
15115 return combineMUL(
N, DCI);
15118 return combineFMALike(
N, DCI);
15121 return N->getOperand(0);
15125 return N->getOperand(0);
15131 return N->getOperand(0);
15137 return DAGCombineExtBoolTrunc(
N, DCI);
15139 return combineTRUNCATE(
N, DCI);
15141 if (
SDValue CSCC = combineSetCC(
N, DCI))
15145 return DAGCombineTruncBoolExt(
N, DCI);
15148 return combineFPToIntToFP(
N, DCI);
15157 EVT Op1VT =
N->getOperand(1).getValueType();
15158 unsigned Opcode =
N->getOperand(1).getOpcode();
15161 SDValue Val= combineStoreFPToInt(
N, DCI);
15175 N->getOperand(1).getNode()->hasOneUse() &&
15192 if (Op1VT.
bitsGT(mVT)) {
15242 EVT VT = LD->getValueType(0);
15261 auto ReplaceTwoFloatLoad = [&]() {
15277 if (!LD->hasNUsesOfValue(2, 0))
15280 auto UI = LD->use_begin();
15281 while (UI.getUse().getResNo() != 0) ++UI;
15283 while (UI.getUse().getResNo() != 0) ++UI;
15284 SDNode *RightShift = *UI;
15292 if (RightShift->getOpcode() !=
ISD::SRL ||
15294 RightShift->getConstantOperandVal(1) != 32 ||
15295 !RightShift->hasOneUse())
15298 SDNode *Trunc2 = *RightShift->use_begin();
15307 if (Bitcast->getOpcode() != ISD::BITCAST ||
15308 Bitcast->getValueType(0) !=
MVT::f32)
15310 if (Bitcast2->
getOpcode() != ISD::BITCAST ||
15320 SDValue BasePtr = LD->getBasePtr();
15321 if (LD->isIndexed()) {
15323 "Non-pre-inc AM on PPC?");
15332 LD->getPointerInfo(), LD->getAlign(),
15333 MMOFlags, LD->getAAInfo());
15339 LD->getPointerInfo().getWithOffset(4),
15342 if (LD->isIndexed()) {
15356 if (ReplaceTwoFloatLoad())
15359 EVT MemVT = LD->getMemoryVT();
15362 if (LD->isUnindexed() && VT.
isVector() &&
15368 LD->getAlign() < ABIAlignment) {
15370 SDValue Chain = LD->getChain();
15371 SDValue Ptr = LD->getBasePtr();
15399 MVT PermCntlTy, PermTy, LDTy;
15400 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
15401 : Intrinsic::ppc_altivec_lvsl;
15402 IntrLD = Intrinsic::ppc_altivec_lvx;
15403 IntrPerm = Intrinsic::ppc_altivec_vperm;
15424 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
15428 BaseLoadOps, LDTy, BaseMMO);
15437 int IncValue = IncOffset;
15454 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
15458 ExtraLoadOps, LDTy, ExtraMMO);
15469 if (isLittleEndian)
15471 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
15474 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
15478 ? DAG.
getNode(ISD::BITCAST, dl, VT, Perm)
15495 : Intrinsic::ppc_altivec_lvsl);
15496 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
15503 .
zext(
Add.getScalarValueSizeInBits()))) {
15504 SDNode *BasePtr =
Add->getOperand(0).getNode();
15505 for (
SDNode *U : BasePtr->uses()) {
15518 SDNode *BasePtr =
Add->getOperand(0).getNode();
15519 for (
SDNode *U : BasePtr->uses()) {
15542 (IID == Intrinsic::ppc_altivec_vmaxsw ||
15543 IID == Intrinsic::ppc_altivec_vmaxsh ||
15544 IID == Intrinsic::ppc_altivec_vmaxsb)) {
15560 V2.getOperand(1) == V1) {
15581 case Intrinsic::ppc_vsx_lxvw4x:
15582 case Intrinsic::ppc_vsx_lxvd2x:
15594 case Intrinsic::ppc_vsx_stxvw4x:
15595 case Intrinsic::ppc_vsx_stxvd2x:
15604 bool Is64BitBswapOn64BitTgt =
15607 N->getOperand(0).hasOneUse();
15608 if (IsSingleUseNormalLd &&
15610 (Subtarget.
hasLDBRX() && Is64BitBswapOn64BitTgt))) {
15623 Ops, LD->getMemoryVT(), LD->getMemOperand());
15644 !IsSingleUseNormalLd)
15649 if (!LD->isSimple())
15651 SDValue BasePtr = LD->getBasePtr();
15653 LD->getPointerInfo(), LD->getAlign());
15658 LD->getMemOperand(), 4, 4);
15668 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
15677 if (!
N->getOperand(0).hasOneUse() &&
15678 !
N->getOperand(1).hasOneUse() &&
15679 !
N->getOperand(2).hasOneUse()) {
15682 SDNode *VCMPrecNode =
nullptr;
15688 UI->getOperand(1) ==
N->getOperand(1) &&
15689 UI->getOperand(2) ==
N->getOperand(2) &&
15690 UI->getOperand(0) ==
N->getOperand(0)) {
15703 SDNode *FlagUser =
nullptr;
15705 FlagUser ==
nullptr; ++UI) {
15706 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
15719 return SDValue(VCMPrecNode, 0);
15722 case ISD::BRCOND: {
15728 Intrinsic::loop_decrement) {
15734 "Counter decrement has more than one use");
15751 if (LHS.getOpcode() ==
ISD::AND &&
15754 Intrinsic::loop_decrement &&
15761 Intrinsic::loop_decrement &&
15764 "Counter decrement comparison is not EQ or NE");
15773 assert(LHS.getNode()->hasOneUse() &&
15774 "Counter decrement has more than one use");
15777 N->getOperand(0),
N->getOperand(4));
15786 assert(isDot &&
"Can't compare against a vector result!");
15791 if (Val != 0 && Val != 1) {
15793 return N->getOperand(0);
15796 N->getOperand(0),
N->getOperand(4));
15799 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
15807 EVT VTs[] = { LHS.getOperand(2).getValueType(),
MVT::Glue };
15836 return DAGCombineBuildVector(
N, DCI);
15838 return combineABS(
N, DCI);
15840 return combineVSelect(
N, DCI);
15851 EVT VT =
N->getValueType(0);
15882 const APInt &DemandedElts,
15884 unsigned Depth)
const {
15886 switch (Op.getOpcode()) {
15891 Known.
Zero = 0xFFFF0000;
15897 case Intrinsic::ppc_altivec_vcmpbfp_p:
15898 case Intrinsic::ppc_altivec_vcmpeqfp_p:
15899 case Intrinsic::ppc_altivec_vcmpequb_p:
15900 case Intrinsic::ppc_altivec_vcmpequh_p:
15901 case Intrinsic::ppc_altivec_vcmpequw_p:
15902 case Intrinsic::ppc_altivec_vcmpequd_p:
15903 case Intrinsic::ppc_altivec_vcmpequq_p:
15904 case Intrinsic::ppc_altivec_vcmpgefp_p:
15905 case Intrinsic::ppc_altivec_vcmpgtfp_p:
15906 case Intrinsic::ppc_altivec_vcmpgtsb_p:
15907 case Intrinsic::ppc_altivec_vcmpgtsh_p:
15908 case Intrinsic::ppc_altivec_vcmpgtsw_p:
15909 case Intrinsic::ppc_altivec_vcmpgtsd_p:
15910 case Intrinsic::ppc_altivec_vcmpgtsq_p:
15911 case Intrinsic::ppc_altivec_vcmpgtub_p:
15912 case Intrinsic::ppc_altivec_vcmpgtuh_p:
15913 case Intrinsic::ppc_altivec_vcmpgtuw_p:
15914 case Intrinsic::ppc_altivec_vcmpgtud_p:
15915 case Intrinsic::ppc_altivec_vcmpgtuq_p:
15925 case Intrinsic::ppc_load2r:
15927 Known.
Zero = 0xFFFF0000;
15957 if (ML->getLoopDepth() > 1 && ML->getSubLoops().empty())
15966 for (
auto I = ML->block_begin(), IE = ML->block_end();
I != IE; ++
I)
15967 for (
auto J = (*I)->begin(), JE = (*I)->end(); J != JE; ++J) {
15968 LoopSize +=
TII->getInstSizeInBytes(*J);
15973 if (LoopSize > 16 && LoopSize <= 32)
15987 if (Constraint.
size() == 1) {
15988 switch (Constraint[0]) {
16006 }
else if (Constraint ==
"wc") {
16008 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
16009 Constraint ==
"wf" || Constraint ==
"ws" ||
16010 Constraint ==
"wi" || Constraint ==
"ww") {
16023 Value *CallOperandVal =
info.CallOperandVal;
16026 if (!CallOperandVal)
16031 if (
StringRef(constraint) ==
"wc" && type->isIntegerTy(1))
16033 else if ((
StringRef(constraint) ==
"wa" ||
16036 type->isVectorTy())
16038 else if (
StringRef(constraint) ==
"wi" && type->isIntegerTy(64))
16040 else if (
StringRef(constraint) ==
"ws" && type->isDoubleTy())
16042 else if (
StringRef(constraint) ==
"ww" && type->isFloatTy())
16045 switch (*constraint) {
16050 if (type->isIntegerTy())
16054 if (type->isFloatTy())
16058 if (type->isDoubleTy())
16062 if (type->isVectorTy())
16075std::pair<unsigned, const TargetRegisterClass *>
16079 if (Constraint.
size() == 1) {
16081 switch (Constraint[0]) {
16084 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
16085 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
16088 return std::make_pair(0U, &PPC::G8RCRegClass);
16089 return std::make_pair(0U, &PPC::GPRCRegClass);
16095 if (Subtarget.
hasSPE()) {
16097 return std::make_pair(0U, &PPC::GPRCRegClass);
16099 return std::make_pair(0U, &PPC::SPERCRegClass);
16102 return std::make_pair(0U, &PPC::F4RCRegClass);
16104 return std::make_pair(0U, &PPC::F8RCRegClass);
16109 return std::make_pair(0U, &PPC::VRRCRegClass);
16110 else if (Subtarget.
hasVSX())
16112 return std::make_pair(0U, &PPC::VFRCRegClass);
16115 return std::make_pair(0U, &PPC::CRRCRegClass);
16117 }
else if (Constraint ==
"wc" && Subtarget.
useCRBits()) {
16119 return std::make_pair(0U, &PPC::CRBITRCRegClass);
16120 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
16121 Constraint ==
"wf" || Constraint ==
"wi") &&
16126 return std::make_pair(0U, &PPC::VSRCRegClass);
16128 return std::make_pair(0U, &PPC::VSSRCRegClass);
16129 return std::make_pair(0U, &PPC::VSFRCRegClass);
16130 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.
hasVSX()) {
16132 return std::make_pair(0U, &PPC::VSSRCRegClass);
16134 return std::make_pair(0U, &PPC::VSFRCRegClass);
16135 }
else if (Constraint ==
"lr") {
16137 return std::make_pair(0U, &PPC::LR8RCRegClass);
16139 return std::make_pair(0U, &PPC::LRRCRegClass);
16144 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
16148 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
16149 int VSNum = atoi(Constraint.
data() + 3);
16150 assert(VSNum >= 0 && VSNum <= 63 &&
16151 "Attempted to access a vsr out of range");
16153 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
16154 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
16159 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
16160 int RegNum = atoi(Constraint.
data() + 2);
16161 if (RegNum > 31 || RegNum < 0)
16164 return Subtarget.
hasSPE()
16165 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
16166 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
16168 return Subtarget.
hasSPE()
16169 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
16170 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
16174 std::pair<unsigned, const TargetRegisterClass *> R =
16184 PPC::GPRCRegClass.contains(R.first))
16185 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
16186 PPC::sub_32, &PPC::G8RCRegClass),
16187 &PPC::G8RCRegClass);
16190 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
16191 R.first = PPC::CR0;
16192 R.second = &PPC::CRRCRegClass;
16196 if (Subtarget.
isAIXABI() && !
TM.getAIXExtendedAltivecABI()) {
16197 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
16198 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
16199 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
16200 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
16201 "default AIX AltiVec ABI and cannot be used\n";
16210 std::string &Constraint,
16211 std::vector<SDValue>&Ops,
16216 if (Constraint.length() > 1)
return;
16218 char Letter = Constraint[0];
16274 if (Result.getNode()) {
16275 Ops.push_back(Result);
16307 switch (AM.
Scale) {
16344 bool isPPC64 = Subtarget.
isPPC64();
16363 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
16384 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
16386 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
16400 bool isPPC64 = Subtarget.
isPPC64();
16452 unsigned Intrinsic)
const {
16453 switch (Intrinsic) {
16454 case Intrinsic::ppc_atomicrmw_xchg_i128:
16455 case Intrinsic::ppc_atomicrmw_add_i128:
16456 case Intrinsic::ppc_atomicrmw_sub_i128:
16457 case Intrinsic::ppc_atomicrmw_nand_i128:
16458 case Intrinsic::ppc_atomicrmw_and_i128:
16459 case Intrinsic::ppc_atomicrmw_or_i128:
16460 case Intrinsic::ppc_atomicrmw_xor_i128:
16461 case Intrinsic::ppc_cmpxchg_i128:
16464 Info.ptrVal =
I.getArgOperand(0);
16466 Info.align =
Align(16);
16470 case Intrinsic::ppc_atomic_load_i128:
16473 Info.ptrVal =
I.getArgOperand(0);
16475 Info.align =
Align(16);
16478 case Intrinsic::ppc_atomic_store_i128:
16481 Info.ptrVal =
I.getArgOperand(2);
16483 Info.align =
Align(16);
16486 case Intrinsic::ppc_altivec_lvx:
16487 case Intrinsic::ppc_altivec_lvxl:
16488 case Intrinsic::ppc_altivec_lvebx:
16489 case Intrinsic::ppc_altivec_lvehx:
16490 case Intrinsic::ppc_altivec_lvewx:
16491 case Intrinsic::ppc_vsx_lxvd2x:
16492 case Intrinsic::ppc_vsx_lxvw4x:
16493 case Intrinsic::ppc_vsx_lxvd2x_be:
16494 case Intrinsic::ppc_vsx_lxvw4x_be:
16495 case Intrinsic::ppc_vsx_lxvl:
16496 case Intrinsic::ppc_vsx_lxvll: {
16498 switch (Intrinsic) {
16499 case Intrinsic::ppc_altivec_lvebx:
16502 case Intrinsic::ppc_altivec_lvehx:
16505 case Intrinsic::ppc_altivec_lvewx:
16508 case Intrinsic::ppc_vsx_lxvd2x:
16509 case Intrinsic::ppc_vsx_lxvd2x_be:
16519 Info.ptrVal =
I.getArgOperand(0);
16522 Info.align =
Align(1);
16526 case Intrinsic::ppc_altivec_stvx:
16527 case Intrinsic::ppc_altivec_stvxl:
16528 case Intrinsic::ppc_altivec_stvebx:
16529 case Intrinsic::ppc_altivec_stvehx:
16530 case Intrinsic::ppc_altivec_stvewx:
16531 case Intrinsic::ppc_vsx_stxvd2x:
16532 case Intrinsic::ppc_vsx_stxvw4x:
16533 case Intrinsic::ppc_vsx_stxvd2x_be:
16534 case Intrinsic::ppc_vsx_stxvw4x_be:
16535 case Intrinsic::ppc_vsx_stxvl:
16536 case Intrinsic::ppc_vsx_stxvll: {
16538 switch (Intrinsic) {
16539 case Intrinsic::ppc_altivec_stvebx:
16542 case Intrinsic::ppc_altivec_stvehx:
16545 case Intrinsic::ppc_altivec_stvewx:
16548 case Intrinsic::ppc_vsx_stxvd2x:
16549 case Intrinsic::ppc_vsx_stxvd2x_be:
16559 Info.ptrVal =
I.getArgOperand(1);
16562 Info.align =
Align(1);
16580 if (Subtarget.
hasAltivec() && Op.size() >= 16 &&
16581 (Op.isAligned(
Align(16)) ||
16597 assert(Ty->isIntegerTy());
16599 unsigned BitSize = Ty->getPrimitiveSizeInBits();
16600 return !(BitSize == 0 || BitSize > 64);
16608 return NumBits1 == 64 && NumBits2 == 32;
16616 return NumBits1 == 64 && NumBits2 == 32;
16623 EVT MemVT = LD->getMemoryVT();
16641 "invalid fpext types");
16658 bool *
Fast)
const {
16676 if (Subtarget.
hasVSX()) {
16700 if (!ConstNode->getAPIntValue().isSignedIntN(64))
16708 int64_t Imm = ConstNode->getSExtValue();
16729 switch (Ty->getScalarType()->getTypeID()) {
16742 if (!
I->hasOneUse())
16746 assert(
User &&
"A single use instruction with no uses.");
16748 switch (
I->getOpcode()) {
16749 case Instruction::FMul: {
16751 if (
User->getOpcode() != Instruction::FSub &&
16752 User->getOpcode() != Instruction::FAdd)
16765 case Instruction::Load: {
16778 if (
User->getOpcode() != Instruction::Store)
16798 static const MCPhysReg ScratchRegs[] = {
16799 PPC::X12, PPC::LR8, PPC::CTR8, 0
16802 return ScratchRegs;
16806 const Constant *PersonalityFn)
const {
16807 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
16811 const Constant *PersonalityFn)
const {
16812 return Subtarget.
isPPC64() ? PPC::X4 : PPC::R4;
16817 EVT VT ,
unsigned DefinedValues)
const {
16855 bool LegalOps,
bool OptForSize,
16857 unsigned Depth)
const {
16861 unsigned Opc = Op.getOpcode();
16862 EVT VT = Op.getValueType();
16871 SDValue N0 = Op.getOperand(0);
16872 SDValue N1 = Op.getOperand(1);
16873 SDValue N2 = Op.getOperand(2);
16887 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
16891 N0Cost,
Depth + 1);
16895 N1Cost,
Depth + 1);
16897 if (NegN0 && N0Cost <= N1Cost) {
16898 Cost = std::min(N0Cost, N2Cost);
16899 return DAG.
getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
16900 }
else if (NegN1) {
16901 Cost = std::min(N1Cost, N2Cost);
16902 return DAG.
getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
16945 bool ForCodeSize)
const {
16962 return Imm.isPosZero();
16974 unsigned Opcode =
N->getOpcode();
16975 unsigned TargetOpcode;
16994 if (Mask->getZExtValue() == OpSizeInBits - 1)
17000SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17030SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17037SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17056 auto isZextOfCompareWithConstant = [](
SDValue Op) {
17061 SDValue Cmp = Op.getOperand(0);
17062 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
17063 Cmp.getOperand(0).getValueType() !=
MVT::i64)
17067 int64_t NegConstant = 0 -
Constant->getSExtValue();
17076 bool LHSHasPattern = isZextOfCompareWithConstant(LHS);
17077 bool RHSHasPattern = isZextOfCompareWithConstant(RHS);
17080 if (LHSHasPattern && !RHSHasPattern)
17082 else if (!LHSHasPattern && !RHSHasPattern)
17087 SDValue Cmp = RHS.getOperand(0);
17090 int64_t NegConstant = 0 -
Constant->getSExtValue();
17155 if (!GSDN || !ConstNode)
17175SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17195 DAGCombinerInfo &DCI)
const {
17199 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
17200 return CRTruncValue;
17208 EVT VT =
N->getValueType(0);
17219 DCI.DAG.getTargetConstant(0, dl,
MVT::i32));
17228 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
17238 EltToExtract = EltToExtract ? 0 : 1;
17248 return DCI.DAG.getNode(
17250 DCI.DAG.getTargetConstant(EltToExtract, dl,
MVT::i32));
17255SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17259 if (!ConstOpOrElement)
17267 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
17290 return IsAddOne && IsNeg ? VT.
isVector() :
true;
17294 EVT VT =
N->getValueType(0);
17301 if ((MulAmtAbs - 1).isPowerOf2()) {
17305 if (!IsProfitable(IsNeg,
true, VT))
17318 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
17322 if (!IsProfitable(IsNeg,
false, VT))
17343 DAGCombinerInfo &DCI)
const {
17348 EVT VT =
N->getValueType(0);
17351 unsigned Opc =
N->getOpcode();
17353 bool LegalOps = !DCI.isBeforeLegalizeOps();
17361 if (!Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
17377bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
17407bool PPCTargetLowering::hasBitPreservingFPLogic(
EVT VT)
const {
17408 if (!Subtarget.
hasVSX())
17416bool PPCTargetLowering::
17417isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
17422 if (CI->getBitWidth() > 64)
17424 int64_t ConstVal = CI->getZExtValue();
17426 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
17438SDValue PPCTargetLowering::combineABS(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17441 "Only combine this when P9 altivec supported!");
17442 EVT VT =
N->getValueType(0);
17448 if (
N->getOperand(0).getOpcode() ==
ISD::SUB) {
17451 unsigned SubOpcd0 =
N->getOperand(0)->getOperand(0).getOpcode();
17452 unsigned SubOpcd1 =
N->getOperand(0)->getOperand(1).getOpcode();
17458 N->getOperand(0)->getOperand(0),
17459 N->getOperand(0)->getOperand(1),
17464 if (
N->getOperand(0).getValueType() ==
MVT::v4i32 &&
17465 N->getOperand(0).hasOneUse()) {
17467 N->getOperand(0)->getOperand(0),
17468 N->getOperand(0)->getOperand(1),
17482 DAGCombinerInfo &DCI)
const {
17485 "Only combine this when P9 altivec supported!");
17492 EVT VT =
N->getOperand(1).getValueType();
17532 CmpOpnd1, CmpOpnd2,
17541PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
17547 if ((Flags & FlagSet) == FlagSet)
17550 if ((Flags & FlagSet) == FlagSet)
17553 if ((Flags & FlagSet) == FlagSet)
17556 if ((Flags & FlagSet) == FlagSet)
17577 if ((FrameIndexAlign % 4) != 0)
17578 FlagSet &= ~PPC::MOF_RPlusSImm16Mult4;
17579 if ((FrameIndexAlign % 16) != 0)
17580 FlagSet &= ~PPC::MOF_RPlusSImm16Mult16;
17584 if ((FrameIndexAlign % 4) == 0)
17586 if ((FrameIndexAlign % 16) == 0)
17599 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
17600 if ((Imm & 0x3) == 0)
17602 if ((Imm & 0xf) == 0)
17608 const APInt &ConstImm = CN->getAPIntValue();
17627 const APInt &ConstImm = CN->getAPIntValue();
17658unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
17679 unsigned ParentOp = Parent->
getOpcode();
17683 if ((ID == Intrinsic::ppc_vsx_lxvp) || (ID == Intrinsic::ppc_vsx_stxvp)) {
17684 SDValue IntrinOp = (ID == Intrinsic::ppc_vsx_lxvp)
17696 if (LSB->isIndexed())
17702 assert(MN &&
"Parent should be a MemSDNode!");
17707 "Not expecting scalar integers larger than 16 bytes!");
17710 else if (
Size == 32)
17717 else if (
Size == 256) {
17719 "256-bit vectors are only available when paired vector memops is "
17758 FlagSet &= ~PPC::MOF_NoExt;
17763 bool IsNonP1034BitConst =
17767 IsNonP1034BitConst)
17780 int16_t ForceXFormImm = 0;
17795 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
17827SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
17831 EVT RetVT = Op.getValueType();
17838 for (
const SDValue &
N : Op->op_values()) {
17839 EVT ArgVT =
N.getValueType();
17844 Entry.IsZExt = !Entry.IsSExt;
17845 Args.push_back(Entry);
17853 (RetTy ==
F.getReturnType() ||
F.getReturnType()->
isVoidTy());
17866SDValue PPCTargetLowering::lowerLibCallBasedOnType(
17867 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
17870 return lowerToLibCall(LibCallFloatName, Op, DAG);
17873 return lowerToLibCall(LibCallDoubleName, Op, DAG);
17878bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
17880 return isLowringToMASSSafe(Op) && Flags.hasNoSignedZeros() &&
17881 Flags.hasNoNaNs() && Flags.hasNoInfs();
17884bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
17885 return Op.getNode()->getFlags().hasApproximateFuncs();
17888bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
17892SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
17893 const char *LibCallFloatName,
17894 const char *LibCallDoubleNameFinite,
17895 const char *LibCallFloatNameFinite,
17898 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(Op))
17901 if (!isLowringToMASSFiniteSafe(Op))
17902 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName, Op,
17905 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
17906 LibCallDoubleNameFinite, Op, DAG);
17910 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
17911 "__xl_powf_finite", Op, DAG);
17915 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
17916 "__xl_sinf_finite", Op, DAG);
17920 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
17921 "__xl_cosf_finite", Op, DAG);
17925 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
17926 "__xl_logf_finite", Op, DAG);
17930 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
17931 "__xl_log10f_finite", Op, DAG);
17935 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
17936 "__xl_expf_finite", Op, DAG);
17961 unsigned Flags = computeMOFlags(Parent,
N, DAG);
17973 "Must be using PC-Relative calls when a valid PC-Relative node is "
18008 Base =
N.getOperand(0);
18016 EVT CNType = CN->getValueType(0);
18017 uint64_t CNImm = CN->getZExtValue();
18030 int32_t
Addr = (int32_t)CNImm;
18051 unsigned Opcode =
N.getOpcode();
18090 bool IsVarArg)
const {
18102 return Subtarget.
isPPC64() &&
18129 return Intrinsic::ppc_atomicrmw_xchg_i128;
18131 return Intrinsic::ppc_atomicrmw_add_i128;
18133 return Intrinsic::ppc_atomicrmw_sub_i128;
18135 return Intrinsic::ppc_atomicrmw_and_i128;
18137 return Intrinsic::ppc_atomicrmw_or_i128;
18139 return Intrinsic::ppc_atomicrmw_xor_i128;
18141 return Intrinsic::ppc_atomicrmw_nand_i128;
18149 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
18151 assert(ValTy->getPrimitiveSizeInBits() == 128);
18155 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
18157 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
18160 Value *LoHi = Builder.CreateCall(RMW, {
Addr, IncrLo, IncrHi});
18161 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
18162 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
18163 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
18164 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
18165 return Builder.CreateOr(
18173 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
18175 assert(ValTy->getPrimitiveSizeInBits() == 128);
18179 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
18181 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
18182 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
18184 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
18189 Builder.CreateCall(IntCmpXchg, {
Addr, CmpLo, CmpHi, NewLo, NewHi});
18191 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
18192 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
18193 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
18194 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
18195 return Builder.CreateOr(
unsigned const MachineRegisterInfo * MRI
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &dl)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDNode *N, SelectionDAG &DAG)
static const unsigned PerfectShuffleTable[6561+1]
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu Simplify well known AMD library false FunctionCallee Callee
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
Function Alias Analysis Results
Atomic ordering constants.
SmallVector< MachineOperand, 4 > Cond
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
unsigned const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isConstantOrUndef(const SDValue Op)
Module.h This file contains the declarations for the Module class.
This file provides None, an enumerator for use in implicit constructors of various (usually templated...
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static bool callsShareTOCBase(const Function *Caller, SDValue Callee, const TargetMachine &TM)
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static bool isFunctionGlobalAddress(SDValue Callee)
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool isPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &S)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static const char AIXSSPCanaryWordName[]
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InFlag, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static cl::opt< bool > DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden)
static Intrinsic::ID getIntrinsicForAtomicRMWBinOp128(AtomicRMWInst::BinOp BinOp)
static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotSize - Calculates the size reserved for this argument on the stack.
static int CalculateTailCallSPDiff(SelectionDAG &DAG, bool isTailCall, unsigned ParamSize)
CalculateTailCallSPDiff - Get the amount the stack pointer has to be adjusted to accommodate the argu...
static Instruction * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSMaxIdx, int RHSMinIdx, int RHSMaxIdx, int HalfVec, unsigned ValidLaneWidth, const PPCSubtarget &Subtarget)
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static cl::opt< bool > EnableQuadwordAtomics("ppc-quadword-atomics", cl::desc("enable quadword lock-free atomic operations"), cl::init(false), cl::Hidden)
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static cl::opt< bool > DisablePerfectShuffle("ppc-disable-perfect-shuffle", cl::desc("disable vector permute decomposition"), cl::init(true), cl::Hidden)
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static bool isValidSplatLoad(const PPCSubtarget &Subtarget, const SDValue &Op, unsigned &Opcode)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static int getEstimateRefinementSteps(EVT VT, const PPCSubtarget &Subtarget)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Given a node, compute flags that are used for address computation when selecting load and store instr...
cl::opt< bool > ANDIGlueBug
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
const char LLVMTargetMachineRef TM
static cl::opt< RegAllocEvictionAdvisorAnalysis::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development, "development", "for training")))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
static bool isSplat(ArrayRef< Value * > VL)
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
This file describes how to lower LLVM code to machine code.
This defines the Use class.
static Optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static bool is64Bit(const char *name)
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
bool isNegative() const
Determine sign of this APInt.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
BinOp getOperation() const
This is an SDNode representing atomic operations.
This class holds the attributes for a function, its return value, and its parameters.
StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
The address of a basic block.
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
CCValAssign - Represent assignment of one arg/retval to a location.
unsigned getLocMemOffset() const
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, unsigned Offset, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, unsigned Offset, MVT LocVT, LocInfo HTP)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
unsigned getValNo() const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
const Function & getFunction() const
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
const GlobalObject * getAliaseeObject() const
StringRef getSection() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
Common base class shared among various IRBuilders.
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag.
@ Kind_RegDefEarlyClobber
static unsigned getKind(unsigned Flags)
const BasicBlock * getParent() const
bool hasAtomicLoad() const
Return true if this atomic instruction loads from memory.
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
@ INVALID_SIMPLE_VALUE_TYPE
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineInstr - Allocate a new MachineInstr.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineModuleInfo & getMMI() const
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
uint64_t getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
const MCContext & getContext() const
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
PICLevel::Level getPICLevel() const
Returns the PIC level (small or large model)
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
uint64_t getFramePointerSaveOffset() const
getFramePointerSaveOffset - Return the previous frame offset to save the frame pointer.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
void setTailCallSPDelta(int size)
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
bool useLongCalls() const
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
bool useSoftFloat() const
bool use64BitRegs() const
use64BitRegs - Return true if in 64-bit mode or if we should use 64-bit registers in 32-bit mode when...
bool allowsUnalignedFPAccess() const
const PPCFrameLowering * getFrameLowering() const override
bool needsSwapsForVSXMemOps() const
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
bool needsTwoConstNR() const
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
bool hasQuadwordAtomics() const
MCRegister getEnvironmentPointerRegister() const
const PPCInstrInfo * getInstrInfo() const override
bool hasP10Vector() const
bool useCRBits() const
useCRBits - Return true if we should store and manipulate i1 values in the individual condition regis...
bool hasRecipPrec() const
bool hasInvariantFunctionDescriptors() const
unsigned getCPUDirective() const
getCPUDirective - Returns the -m directive specified for the cpu.
POPCNTDKind hasPOPCNTD() const
bool hasPrefixInstrs() const
bool hasPartwordAtomics() const
bool isLittleEndian() const
bool isTargetLinux() const
bool hasP9Altivec() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
bool has64BitSupport() const
has64BitSupport - Return true if the selected CPU supports 64-bit instructions, regardless of whether...
bool is64BitELFABI() const
bool pairedVectorMemops() const
const PPCTargetMachine & getTargetMachine() const
bool isPredictableSelectIsExpensive() const
bool enableMachineScheduler() const override
Scheduling customization.
const PPCRegisterInfo * getRegisterInfo() const override
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
const Triple & getTargetTriple() const
unsigned descriptorEnvironmentPointerOffset() const
bool hasDirectMove() const
bool hasP8Altivec() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
unsigned getStackProbeSize(MachineFunction &MF) const
CCAssignFn * ccAssignFnForCall(CallingConv::ID CC, bool Return, bool IsVarArg) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
SelectForceXFormMode - Given the specified address, force it to be represented as an indexed [r+r] op...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
const char * getTargetNodeName(unsigned Opcode) const override
getTargetNodeName() - This method returns the name of a target specific DAG node.
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, bool is8bit, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, Optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned AtomicSize, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
void insertSSPDeclarations(Module &M) const override
Inserts necessary declarations for SSP (stack protection) purpose.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
uint64_t getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
EVT getOptimalMemOpType(const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
bool useLoadStackGuardNode() const override
Override to support customized stack guard loading.
bool hasInlineStackProbe(MachineFunction &MF) const override
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=None) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, bool *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isJumpTableRelative() const override
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
Value * getSDagStackGuard(const Module &M) const override
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
Wrapper class representing virtual and physical registers.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
bool isPredecessorOf(const SDNode *N) const
Return true if this node is a predecessor of N.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
op_iterator op_end() const
op_iterator op_begin() const
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS)
Helper function to make it easier to build Select's if you just have operands and don't want to check...
SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=None, int Offset=0, unsigned TargetFlags=0)
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond)
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, uint64_t Size=0, const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
SDValue getRegisterMask(const uint32_t *RegMask)
SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
SDValue getCondCode(ISD::CondCode Cond)
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
const_iterator begin() const
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
const_iterator end() const
LLVM_NODISCARD bool empty() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
LLVM_NODISCARD T pop_back_val()
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset is a class to represent an offset with 2 dimensions, named fixed and scalable,...
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
LLVM_NODISCARD constexpr size_t size() const
size - Get the string size.
std::enable_if_t< std::numeric_limits< T >::is_signed, bool > getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
A switch()-like statement whose cases are string literals.
LLVM_NODISCARD R Default(T Value)
StringSwitch & Case(StringLiteral S, T Value)
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
virtual bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
virtual MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
virtual Value * getSDagStackGuard(const Module &M) const
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?...
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL, bool LegalTypes=true) const
Returns the type for the shift amount of a shift opcode.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
virtual AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
NegatibleCost
Enum that specifies when a float negation is beneficial.
std::vector< ArgListEntry > ArgListTy
void setHasMultipleConditionRegisters(bool hasManyRegs=true)
Tells the code generator that the target has multiple (allocatable) condition registers that can be u...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
virtual void insertSSPDeclarations(Module &M) const
Inserts necessary declarations for SSP (stack protection) purpose.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
virtual bool useLoadStackGuardNode() const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const
Check whether a given call node is in tail position within its function.
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
Primary interface to the complete machine description for the target machine.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const
CodeModel::Model getCodeModel() const
Returns the code model.
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
unsigned NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
unsigned PPCGenScalarMASSEntries
Enables scalar MASS conversions.
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static TypeSize Fixed(ScalarTy MinVal)
The instances of the Type class are immutable: once they are created, they are never changed.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
static IntegerType * getInt64Ty(LLVMContext &C)
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
static Type * getVoidTy(LLVMContext &C)
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isVoidTy() const
Return true if this is 'void'.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Fast
Fast - This calling convention attempts to make calls as fast as possible (e.g.
@ C
C - The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ FLT_ROUNDS_
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ ADD
Simple integer binary arithmetic operators.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_GOT_FLAG
MO_GOT_FLAG - If this bit is set the symbol reference is to be computed via the GOT.
@ MO_PLT
On a symbol operand "FOO", this indicates that the reference is actually to "FOO@plt".
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set the symbol reference is relative to TLS Initial Exec model.
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ SEXT_LD_SPLAT
VSRC, CHAIN = SEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory that sign-extends.
@ FCTIDUZ
Newer FCTI[D,W]UZ floating-point-to-integer conversion instructions for unsigned integers with round ...
@ ADDI_TLSGD_L_ADDR
G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSGD_L and GET_TLS_ADDR unti...
@ FSQRT
Square root instruction.
@ STRICT_FCFID
Constrained integer-to-floating-point conversion instructions.
@ DYNALLOC
The following two target-specific nodes are used for calls through function pointers in the 64-bit SV...
@ COND_BRANCH
CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This corresponds to the COND_BRANCH pseudo ...
@ VABSD
An SDNode for Power9 vector absolute value difference.
@ CALL_RM
The variants that implicitly define rounding mode for calls with strictfp semantics.
@ STORE_VEC_BE
CHAIN = STORE_VEC_BE CHAIN, VSRC, Ptr - Occurs only for little endian.
@ BDNZ
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
@ MTVSRZ
Direct move from a GPR to a VSX register (zero)
@ SRL
These nodes represent PPC shifts.
@ VECINSERT
VECINSERT - The PPC vector insert instruction.
@ LXSIZX
GPRC, CHAIN = LXSIZX, CHAIN, Ptr, ByteWidth - This is a load of an integer smaller than 64 bits into ...
@ FNMSUB
FNMSUB - Negated multiply-subtract instruction.
@ RFEBB
CHAIN = RFEBB CHAIN, State - Return from event-based branch.
@ FCTIDZ
FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 operand, producing an f64 value...
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ GET_TLS_ADDR
x3 = GET_TLS_ADDR x3, Symbol - For the general-dynamic TLS model, produces a call to __tls_get_addr(s...
@ FP_TO_UINT_IN_VSR
Floating-point-to-integer conversion instructions.
@ XXSPLTI32DX
XXSPLTI32DX - The PPC XXSPLTI32DX instruction.
@ ANDI_rec_1_EQ_BIT
i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the eq or gt bit of CR0 after ex...
@ FRE
Reciprocal estimate instructions (unary FP ops).
@ ADDIS_GOT_TPREL_HA
G8RC = ADDIS_GOT_TPREL_HA x2, Symbol - Used by the initial-exec TLS model, produces an ADDIS8 instruc...
@ CLRBHRB
CHAIN = CLRBHRB CHAIN - Clear branch history rolling buffer.
@ SINT_VEC_TO_FP
Extract a subvector from signed integer vector and convert to FP.
@ EXTRACT_SPE
Extract SPE register component, second argument is high or low.
@ XXSWAPD
VSRC, CHAIN = XXSWAPD CHAIN, VSRC - Occurs only for little endian.
@ ADDI_TLSLD_L_ADDR
G8RC = ADDI_TLSLD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSLD_L and GET_TLSLD_ADDR un...
@ ATOMIC_CMP_SWAP_8
ATOMIC_CMP_SWAP - the exact same as the target-independent nodes except they ensure that the compare ...
@ ST_VSR_SCAL_INT
Store scalar integers from VSR.
@ VCMP
RESVEC = VCMP(LHS, RHS, OPC) - Represents one of the altivec VCMP* instructions.
@ BCTRL
CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a BCTRL instruction.
@ BUILD_SPE64
BUILD_SPE64 and EXTRACT_SPE are analogous to BUILD_PAIR and EXTRACT_ELEMENT but take f64 arguments in...
@ LFIWZX
GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a floating-point load which zero-extends from a 32-bit inte...
@ SCALAR_TO_VECTOR_PERMUTED
PowerPC instructions that have SCALAR_TO_VECTOR semantics tend to place the value into the least sign...
@ EXTRACT_VSX_REG
EXTRACT_VSX_REG = Extract one of the underlying vsx registers of an accumulator or pair register.
@ STXSIX
STXSIX - The STXSI[bh]X instruction.
@ MAT_PCREL_ADDR
MAT_PCREL_ADDR = Materialize a PC Relative address.
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ XXSPLT
XXSPLT - The PPC VSX splat instructions.
@ TOC_ENTRY
GPRC = TOC_ENTRY GA, TOC Loads the entry for GA from the TOC, where the TOC base is given by the last...
@ XXPERMDI
XXPERMDI - The PPC XXPERMDI instruction.
@ ADDIS_DTPREL_HA
G8RC = ADDIS_DTPREL_HA x3, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction t...
@ ADD_TLS
G8RC = ADD_TLS G8RReg, Symbol - Used by the initial-exec TLS model, produces an ADD instruction that ...
@ MTVSRA
Direct move from a GPR to a VSX register (algebraic)
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_GOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ ADDI_DTPREL_L
G8RC = ADDI_DTPREL_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction ...
@ BCTRL_LOAD_TOC
CHAIN,FLAG = BCTRL(CHAIN, ADDR, INFLAG) - The combination of a bctrl instruction and the TOC reload r...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ FCFID
FCFID - The FCFID instruction, taking an f64 operand and producing and f64 value containing the FP re...
@ CR6SET
ch, gl = CR6[UN]SET ch, inglue - Toggle CR bit 6 for SVR4 vararg calls
@ LBRX
GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a byte-swapping load instruction.
@ LD_VSX_LH
VSRC, CHAIN = LD_VSX_LH CHAIN, Ptr - This is a floating-point load of a v2f32 value into the lower ha...
@ PROBED_ALLOCA
To avoid stack clash, allocation is performed by block and each block is probed.
@ XXMFACC
XXMFACC = This corresponds to the xxmfacc instruction.
@ ADDIS_TLSGD_HA
G8RC = ADDIS_TLSGD_HA x2, Symbol - For the general-dynamic TLS model, produces an ADDIS8 instruction ...
@ ACC_BUILD
ACC_BUILD = Build an accumulator register from 4 VSX registers.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ LXVD2X
VSRC, CHAIN = LXVD2X_LE CHAIN, Ptr - Occurs only for little endian.
@ XSMAXC
XSMAXC[DQ]P, XSMINC[DQ]P - C-type min/max instructions.
@ CALL
CALL - A direct function call.
@ MTCTR
CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a MTCTR instruction.
@ TC_RETURN
TC_RETURN - A tail call return.
@ STFIWX
STFIWX - The STFIWX instruction.
@ LD_SPLAT
VSRC, CHAIN = LD_SPLAT, CHAIN, Ptr - a splatting load memory instructions such as LXVDSX,...
@ VCMP_rec
RESVEC, OUTFLAG = VCMP_rec(LHS, RHS, OPC) - Represents one of the altivec VCMP*_rec instructions.
@ MFFS
F8RC = MFFS - This moves the FPSCR (not modeled) into the register.
@ PADDI_DTPREL
G8RC = PADDI_DTPREL x3, Symbol - For the pc-rel based local-dynamic TLS model, produces a PADDI8 inst...
@ BUILD_FP128
Direct move of 2 consecutive GPR to a VSX register.
@ VEXTS
VEXTS, ByteWidth - takes an input in VSFRC and produces an output in VSFRC that is sign-extended from...
@ TLS_LOCAL_EXEC_MAT_ADDR
TLS_LOCAL_EXEC_MAT_ADDR = Materialize an address for TLS global address when using local exec access ...
@ VPERM
VPERM - The PPC VPERM Instruction.
@ ADDIS_TLSLD_HA
G8RC = ADDIS_TLSLD_HA x2, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction th...
@ XXSPLTI_SP_TO_DP
XXSPLTI_SP_TO_DP - The PPC VSX splat instructions for immediates for converting immediate single prec...
@ GET_TLSLD_ADDR
x3 = GET_TLSLD_ADDR x3, Symbol - For the local-dynamic TLS model, produces a call to __tls_get_addr(s...
@ ADDI_TLSGD_L
x3 = ADDI_TLSGD_L G8RReg, Symbol - For the general-dynamic TLS model, produces an ADDI8 instruction t...
@ DYNAREAOFFSET
This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to compute an offset from native ...
@ PAIR_BUILD
PAIR_BUILD = Build a vector pair register from 2 VSX registers.
@ STRICT_FADDRTZ
Constrained floating point add in round-to-zero mode.
@ FTSQRT
Test instruction for software square root.
@ FP_EXTEND_HALF
FP_EXTEND_HALF(VECTOR, IDX) - Custom extend upper (IDX=0) half or lower (IDX=1) half of v4f32 to v2f6...
@ RET_FLAG
Return with a flag operand, matched by 'blr'.
@ CMPB
The CMPB instruction (takes two operands of i32 or i64).
@ VECSHL
VECSHL - The PPC vector shift left instruction.
@ ADDI_TLSLD_L
x3 = ADDI_TLSLD_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction tha...
@ FADDRTZ
F8RC = FADDRTZ F8RC, F8RC - This is an FADD done with rounding towards zero.
@ ZEXT_LD_SPLAT
VSRC, CHAIN = ZEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory that zero-extends.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
@ EXTSWSLI
EXTSWSLI = The PPC extswsli instruction, which does an extend-sign word and shift left immediate.
@ STXVD2X
CHAIN = STXVD2X CHAIN, VSRC, Ptr - Occurs only for little endian.
@ TLSGD_AIX
GPRC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY G8RC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY Op that combines two re...
@ UINT_VEC_TO_FP
Extract a subvector from unsigned integer vector and convert to FP.
@ LXVRZX
LXVRZX - Load VSX Vector Rightmost and Zero Extend This node represents v1i128 BUILD_VECTOR of a zero...
@ MFBHRBE
GPRC, CHAIN = MFBHRBE CHAIN, Entry, Dummy - Move from branch history rolling buffer entry.
@ FCFIDU
Newer FCFID[US] integer-to-floating-point conversion instructions for unsigned integers and single-pr...
@ FSEL
FSEL - Traditional three-operand fsel node.
@ SWAP_NO_CHAIN
An SDNode for swaps that are not associated with any loads/stores and thereby have no chain.
@ LOAD_VEC_BE
VSRC, CHAIN = LOAD_VEC_BE CHAIN, Ptr - Occurs only for little endian.
@ LFIWAX
GPRC, CHAIN = LFIWAX CHAIN, Ptr - This is a floating-point load which sign-extends from a 32-bit inte...
@ STBRX
CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a byte-swapping store instruction.
@ LD_GOT_TPREL_L
G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec TLS model, produces a LD instruction ...
@ MFVSR
Direct move from a VSX register to a GPR.
@ TLS_DYNAMIC_MAT_PCREL_ADDR
TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for TLS global address when using dyna...
@ Hi
Hi/Lo - These represent the high and low 16-bit parts of a global address respectively.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
@ Define
Register definition.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
static bool isIndirectCall(const MachineInstr &MI)
constexpr bool isUInt< 16 >(uint64_t x)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
bool CC_PPC64_ELF_FIS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
LLVM_NODISCARD bool isa_and_nonnull(const Y &Val)
SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
LLVM_NODISCARD decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_NODISCARD decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isInt< 32 >(int64_t x)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
constexpr bool isInt< 16 >(int64_t x)
LLVM_NODISCARD bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
uint32_t FloatToBits(float Float)
This function takes a float and returns the bit equivalent 32-bit integer.
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
uint64_t PowerOf2Floor(uint64_t A)
Returns the power of two which is less than or equal to the given value.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
unsigned countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1.
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Mod
The access may modify the value stored in memory.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
@ Z
zlib style complession
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
@ Mul
Product of integers.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
unsigned M0(unsigned Val)
ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr unsigned BitWidth
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble() LLVM_READNONE
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg If BaseGV is null...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setTailCall(bool Value=true)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)